From f61de153c3a6dc14e9cf7a0608ff6339422b0feb Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 11 Apr 2024 00:46:54 -0500 Subject: [PATCH 1/2] refactor: move FrontMatter creating from parsing from IMetadataParser to it's own class --- source/Models/FrontMatter.cs | 55 ++++++++++++++++++++++++ source/Models/Site.cs | 20 ++++++--- source/Parsers/IMetadataParser.cs | 14 +------ source/Parsers/YAMLParser.cs | 20 +++++++++ test/Models/SiteTests.cs | 53 +++++++++++++---------- test/Parser/YAMLParserTests.cs | 70 +++++++++++++------------------ test/TestSetup.cs | 6 +-- 7 files changed, 153 insertions(+), 85 deletions(-) diff --git a/source/Models/FrontMatter.cs b/source/Models/FrontMatter.cs index b4ac972..3b57c09 100644 --- a/source/Models/FrontMatter.cs +++ b/source/Models/FrontMatter.cs @@ -1,3 +1,6 @@ +using Serilog; +using SuCoS.Helpers; +using SuCoS.Parser; using YamlDotNet.Serialization; namespace SuCoS.Models; @@ -104,4 +107,56 @@ public class FrontMatter : IFrontMatter SourceRelativePath = sourcePath; SourceFullPath = sourcePath; } + + /// + /// Create a front matter from a given metadata + content + /// + /// + /// + /// + /// + /// + /// + public static FrontMatter Parse( + string metadata, + in string rawContent, + in string fileFullPath, + in string fileRelativePath, + IMetadataParser parser + ) + { + Log.Warning($"{parser is null}"); + ArgumentNullException.ThrowIfNull(parser); + + var frontMatter = parser.Parse(metadata); + var section = SiteHelper.GetSection(fileRelativePath); + frontMatter.RawContent = rawContent; + frontMatter.Section = section; + frontMatter.SourceRelativePath = fileRelativePath; + frontMatter.SourceFullPath = fileFullPath; + frontMatter.Type ??= section; + return frontMatter; + } + + /// + /// Create a front matter from a given content + /// + /// + /// + /// + /// + /// + public static FrontMatter Parse( + in string fileFullPath, + in string fileRelativePath, + IMetadataParser parser, + string content + ) + { + Log.Warning($"{parser is null}"); + ArgumentNullException.ThrowIfNull(parser); + + var (metadata, rawContent) = parser.SplitFrontMatter(content); + return Parse(metadata, rawContent, fileFullPath, fileRelativePath, parser); + } } diff --git a/source/Models/Site.cs b/source/Models/Site.cs index 53128c2..45b4893 100644 --- a/source/Models/Site.cs +++ b/source/Models/Site.cs @@ -343,13 +343,19 @@ public class Site : ISite } } - private Page? ParseSourceFile(in string filePath, in IPage? parent, BundleType bundleType = BundleType.none) + private Page? ParseSourceFile(in string fileFullPath, in IPage? parent, BundleType bundleType = BundleType.none) { Page? page = null; try { - var frontMatter = Parser.ParseFrontmatterAndMarkdownFromFile(filePath, SourceContentPath) - ?? throw new FormatException($"Error parsing front matter for {filePath}"); + var content = File.ReadAllText(fileFullPath); + var fileRelativePath = Path.GetRelativePath( + SourceContentPath ?? string.Empty, + fileFullPath + ); + var frontMatter = FrontMatter.Parse(fileFullPath, SourceContentPath, Parser, content) + //?? throw new FormatException($"Error parsing front matter for {fileFullPath}"); + ; if (IsValidPage(frontMatter, Options)) { @@ -360,9 +366,13 @@ public class Site : ISite PostProcessPage(page, parent, true); } } - catch (Exception ex) + catch (FileNotFoundException ex) { - Logger.Error(ex, "Error parsing file {file}", filePath); + Logger.Error(ex, "Error parsing file {file}", fileFullPath); + } + catch (FormatException ex) + { + Logger.Error(ex, "Error parsing file {file}", fileFullPath); } // Use interlocked to safely increment the counter in a multi-threaded environment diff --git a/source/Parsers/IMetadataParser.cs b/source/Parsers/IMetadataParser.cs index 84d2930..27b4547 100644 --- a/source/Parsers/IMetadataParser.cs +++ b/source/Parsers/IMetadataParser.cs @@ -1,5 +1,3 @@ -using SuCoS.Models; - namespace SuCoS.Parser; /// @@ -7,22 +5,12 @@ namespace SuCoS.Parser; /// public interface IMetadataParser { - /// - /// Extract the front matter from the content file. - /// - /// - /// - /// - IFrontMatter? ParseFrontmatterAndMarkdownFromFile(in string fileFullPath, in string sourceContentPath); - /// /// Extract the front matter from the content. /// - /// /// - /// /// - IFrontMatter? ParseFrontmatterAndMarkdown(in string fileFullPath, in string fileRelativePath, in string fileContent); + (string, string) SplitFrontMatter(in string fileContent); /// /// Parse a string content to the T class. diff --git a/source/Parsers/YAMLParser.cs b/source/Parsers/YAMLParser.cs index 7c1fbd7..a4d3646 100644 --- a/source/Parsers/YAMLParser.cs +++ b/source/Parsers/YAMLParser.cs @@ -26,6 +26,26 @@ public class YAMLParser : IMetadataParser .Build(); } + /// + public (string, string) SplitFrontMatter(in string fileContent) + { + using var content = new StringReader(fileContent); + var frontMatterBuilder = new StringBuilder(); + string? line; + + while ((line = content.ReadLine()) != null && line != "---") { } + while ((line = content.ReadLine()) != null && line != "---") + { + _ = frontMatterBuilder.AppendLine(line); + } + + // Join the read lines to form the front matter + var yaml = frontMatterBuilder.ToString(); + var rawContent = content.ReadToEnd(); + + return (yaml, rawContent); + } + /// public IFrontMatter ParseFrontmatterAndMarkdownFromFile( in string fileFullPath, diff --git a/test/Models/SiteTests.cs b/test/Models/SiteTests.cs index 9207cb4..ab3e440 100644 --- a/test/Models/SiteTests.cs +++ b/test/Models/SiteTests.cs @@ -17,10 +17,11 @@ public class SiteTests : TestSetup { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); var siteFullPath = Path.GetFullPath(Path.Combine(testSitesPath, testSitePathCONST01)); - site.Options = new GenerateOptions + + site = new Site(new GenerateOptions { SourceArgument = siteFullPath - }; + }, siteSettingsMock, metadataParser, loggerMock, null); // Act site.ParseAndScanSourceFiles(Path.Combine(siteFullPath, "content")); @@ -69,25 +70,25 @@ public class SiteTests : TestSetup Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page && page.IsSection).Count()); } - [Theory] - [InlineData(testSitePathCONST01, 5)] - [InlineData(testSitePathCONST02, 1)] - [InlineData(testSitePathCONST03, 13)] - [InlineData(testSitePathCONST04, 26)] - public void PagesReference_ShouldReturnExpectedQuantityOfPages(string sitePath, int expectedQuantity) - { - GenerateOptions options = new() - { - SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) - }; - site.Options = options; - - // Act - site.ParseAndScanSourceFiles(null); - - // Assert - Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page).Count()); - } + // [Theory] + // [InlineData(testSitePathCONST01, 5)] + // [InlineData(testSitePathCONST02, 1)] + // [InlineData(testSitePathCONST03, 13)] + // [InlineData(testSitePathCONST04, 26)] + // public void PagesReference_ShouldReturnExpectedQuantityOfPages(string sitePath, int expectedQuantity) + // { + // GenerateOptions options = new() + // { + // SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) + // }; + // site.Options = options; + + // // Act + // site.ParseAndScanSourceFiles(null); + + // // Assert + // Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page).Count()); + // } [Theory] [InlineData(testSitePathCONST01, 4)] @@ -100,11 +101,19 @@ public class SiteTests : TestSetup { SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) }; - site.Options = options; + var parser = new SuCoS.Parser.YAMLParser(); + site = new Site(options, siteSettingsMock, parser, loggerMock, null); // Act site.ParseAndScanSourceFiles(null); + foreach (var page in site.Pages) + { + // Console.WriteLine($"## {(page as Page).frontMatter.Tags} {page.Permalink}"); + } + Console.WriteLine($"{site.Pages.Count()}----"); + Console.WriteLine($"{site.OutputReferences.Values.Count()}-{expectedQuantity}----"); + // Assert Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page && page.IsPage).Count()); } diff --git a/test/Parser/YAMLParserTests.cs b/test/Parser/YAMLParserTests.cs index 4f8c8ff..09eb53e 100644 --- a/test/Parser/YAMLParserTests.cs +++ b/test/Parser/YAMLParserTests.cs @@ -93,7 +93,7 @@ Date: 2023-04-01 public void ParseFrontmatter_ShouldParseTitleCorrectly(string fileContent, string expectedTitle) { // Arrange - var frontMatter = parser.ParseFrontmatterAndMarkdown(fileRelativePathCONST, fileFullPathCONST, fileContent); + var frontMatter = FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, fileContent); // Assert Assert.Equal(expectedTitle, frontMatter.Title); @@ -114,7 +114,7 @@ Date: 2023/01/01 var expectedDate = DateTime.Parse(expectedDateString, CultureInfo.InvariantCulture); // Act - var frontMatter = parser.ParseFrontmatterAndMarkdown(fileRelativePathCONST, fileFullPathCONST, fileContent); + var frontMatter = FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, fileContent); // Assert Assert.Equal(expectedDate, frontMatter.Date); @@ -130,7 +130,7 @@ Date: 2023/01/01 var expectedExpiryDate = DateTime.Parse("2024-06-01", CultureInfo.InvariantCulture); // Act - var frontMatter = parser.ParseFrontmatterAndMarkdown(fileRelativePathCONST, fileFullPathCONST, pageContent); + var frontMatter = FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, pageContent); // Assert Assert.Equal("Test Title", frontMatter.Title); @@ -151,7 +151,9 @@ Title "; // Assert - Assert.Throws(() => parser.ParseFrontmatterAndMarkdown(fileRelativePathCONST, fileFullPathCONST, fileContent)); + Assert.Throws(() => + FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, fileContent) + ); } [Fact] @@ -172,7 +174,8 @@ Title public void ParseParams_ShouldFillParamsWithNonMatchingFields() { // Arrange - var page = new Page(parser.ParseFrontmatterAndMarkdown(string.Empty, string.Empty, pageContent), site); + var frontMatter = FrontMatter.Parse(string.Empty, string.Empty, parser, pageContent); + var page = new Page(frontMatter, site); // Assert Assert.False(page.Params.ContainsKey("customParam")); @@ -184,7 +187,8 @@ Title { // Arrange var date = DateTime.Parse("2023-07-01", CultureInfo.InvariantCulture); - var frontMatter = parser.ParseFrontmatterAndMarkdown(string.Empty, string.Empty, pageContent); + var frontMatter = FrontMatter.Parse(string.Empty, string.Empty, parser, pageContent); + Page page = new(frontMatter, site); // Act @@ -198,7 +202,7 @@ Title public void ParseFrontmatter_ShouldCreateTags() { // Arrange - var frontMatter = parser.ParseFrontmatterAndMarkdown(string.Empty, string.Empty, pageContent); + var frontMatter = FrontMatter.Parse(string.Empty, string.Empty, parser, pageContent); Page page = new(frontMatter, site); // Act @@ -208,41 +212,23 @@ Title Assert.Equal(2, page.TagsReference.Count); } - [Fact] - public void ParseFrontmatter_ShouldThrowExceptionWhenSiteIsNull() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdownFromFile(null!, "fakeFilePath")); - } - - [Fact] - public void ParseFrontmatter_ShouldThrowExceptionWhenFilePathIsNull() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdownFromFile(null!)); - } - - [Fact] - public void ParseFrontmatter_ShouldThrowExceptionWhenFilePathDoesNotExist() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdownFromFile("fakePath")); - } - - [Fact] - public void ParseFrontmatter_ShouldThrowExceptionWhenFilePathDoesNotExist2() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdown(null!, null!, "fakeContent")); - } + // [Fact] + // public void ParseFrontmatter_ShouldThrowExceptionWhenFilePathDoesNotExist2() + // { + // _ = Assert.Throws(() => parser.SplitFrontMatter(null!, null!, "fakeContent")); + // } - [Fact] - public void ParseFrontmatter_ShouldHandleEmptyFileContent() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdown("fakeFilePath", "/fakeFilePath", string.Empty)); - } + // [Fact] + // public void ParseFrontmatter_ShouldHandleEmptyFileContent() + // { + // _ = Assert.Throws(() => parser.SplitFrontMatter("fakeFilePath", "/fakeFilePath", string.Empty)); + // } - [Fact] - public void ParseYAML_ShouldThrowExceptionWhenFrontmatterIsInvalid() - { - _ = Assert.Throws(() => parser.ParseFrontmatterAndMarkdown("fakeFilePath", "/fakeFilePath", "invalidFrontmatter")); - } + // [Fact] + // public void ParseYAML_ShouldThrowExceptionWhenFrontmatterIsInvalid() + // { + // _ = Assert.Throws(() => parser.SplitFrontMatter("fakeFilePath", "/fakeFilePath", "invalidFrontmatter")); + // } [Fact] public void ParseSiteSettings_ShouldReturnSiteSettings() @@ -260,7 +246,7 @@ Title public void ParseSiteSettings_ShouldReturnContent() { // Arrange - var frontMatter = parser.ParseFrontmatterAndMarkdown("fakeFilePath", "/fakeFilePath", pageContent); + var frontMatter = FrontMatter.Parse("fakeFilePath", "/fakeFilePath", parser, pageContent); // Assert Assert.Equal(pageMarkdownCONST, frontMatter.RawContent); @@ -278,7 +264,7 @@ Title { // Arrange var siteSettings = parser.Parse(siteContentCONST); - site = new Site(generateOptionsMock, siteSettings, frontMatterParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettings, metadataParser, loggerMock, systemClockMock); // Assert Assert.NotEmpty(siteSettings.Params); diff --git a/test/TestSetup.cs b/test/TestSetup.cs index c43fa1d..d628c37 100644 --- a/test/TestSetup.cs +++ b/test/TestSetup.cs @@ -23,7 +23,7 @@ public class TestSetup protected const string testSitePathCONST07 = ".TestSites/07-theme-no-baseof-error"; protected const string testSitePathCONST08 = ".TestSites/08-theme-html"; - protected readonly IMetadataParser frontMatterParser = new SuCoS.Parser.YAMLParser(); + protected readonly IMetadataParser metadataParser = new SuCoS.Parser.YAMLParser(); protected readonly IGenerateOptions generateOptionsMock = Substitute.For(); protected readonly SiteSettings siteSettingsMock = Substitute.For(); protected readonly ILogger loggerMock = Substitute.For(); @@ -43,12 +43,12 @@ public class TestSetup public TestSetup() { _ = systemClockMock.Now.Returns(todayDate); - site = new Site(generateOptionsMock, siteSettingsMock, frontMatterParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettingsMock, metadataParser, loggerMock, systemClockMock); } public TestSetup(SiteSettings siteSettings) { _ = systemClockMock.Now.Returns(todayDate); - site = new Site(generateOptionsMock, siteSettings, frontMatterParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettings, metadataParser, loggerMock, systemClockMock); } } -- GitLab From a63e9d966dcb0f432e4f5a9b9b55e9b6d58e01ab Mon Sep 17 00:00:00 2001 From: Bruno Massa Date: Thu, 11 Apr 2024 01:51:12 -0500 Subject: [PATCH 2/2] refactor: move FrontMatter creating from parsing from IMetadataParser to it's own class --- source/Models/FrontMatter.cs | 6 +- source/Models/Site.cs | 16 ++-- source/Parsers/IMetadataParser.cs | 2 + source/Parsers/YAMLParser.cs | 146 +++++++++++------------------- test/Models/SiteTests.cs | 53 +++++------ test/Parser/YAMLParserTests.cs | 55 +++++------ test/TestSetup.cs | 6 +- 7 files changed, 117 insertions(+), 167 deletions(-) diff --git a/source/Models/FrontMatter.cs b/source/Models/FrontMatter.cs index 3b57c09..2895bd8 100644 --- a/source/Models/FrontMatter.cs +++ b/source/Models/FrontMatter.cs @@ -125,7 +125,8 @@ public class FrontMatter : IFrontMatter IMetadataParser parser ) { - Log.Warning($"{parser is null}"); + ArgumentNullException.ThrowIfNull(fileFullPath); + ArgumentNullException.ThrowIfNull(fileRelativePath); ArgumentNullException.ThrowIfNull(parser); var frontMatter = parser.Parse(metadata); @@ -153,7 +154,8 @@ public class FrontMatter : IFrontMatter string content ) { - Log.Warning($"{parser is null}"); + ArgumentNullException.ThrowIfNull(fileFullPath); + ArgumentNullException.ThrowIfNull(fileRelativePath); ArgumentNullException.ThrowIfNull(parser); var (metadata, rawContent) = parser.SplitFrontMatter(content); diff --git a/source/Models/Site.cs b/source/Models/Site.cs index fb7190d..a70d290 100644 --- a/source/Models/Site.cs +++ b/source/Models/Site.cs @@ -1,3 +1,4 @@ +using CommandLine; using Serilog; using SuCoS.Helpers; using SuCoS.Models.CommandLineOptions; @@ -335,14 +336,15 @@ public class Site : ISite Page? page = null; try { - var content = File.ReadAllText(fileFullPath); + var fileContent = File.ReadAllText(fileFullPath); var fileRelativePath = Path.GetRelativePath( SourceContentPath ?? string.Empty, fileFullPath ); - var frontMatter = FrontMatter.Parse(fileFullPath, SourceContentPath, Parser, content) - //?? throw new FormatException($"Error parsing front matter for {fileFullPath}"); - ; + // var frontMatter = Parser.ParseFrontmatterAndMarkdown(fileFullPath, fileRelativePath, fileContent) + // ?? throw new FormatException($"Error parsing front matter for {fileFullPath}"); + var frontMatter = FrontMatter.Parse(fileFullPath, fileRelativePath, Parser, fileContent) + ?? throw new FormatException($"Error parsing front matter for {fileFullPath}"); if (IsValidPage(frontMatter, Options)) { @@ -353,11 +355,7 @@ public class Site : ISite PostProcessPage(page, parent, true); } } - catch (FileNotFoundException ex) - { - Logger.Error(ex, "Error parsing file {file}", fileFullPath); - } - catch (FormatException ex) + catch (Exception ex) { Logger.Error(ex, "Error parsing file {file}", fileFullPath); } diff --git a/source/Parsers/IMetadataParser.cs b/source/Parsers/IMetadataParser.cs index 27b4547..21974a9 100644 --- a/source/Parsers/IMetadataParser.cs +++ b/source/Parsers/IMetadataParser.cs @@ -1,3 +1,5 @@ +using SuCoS.Models; + namespace SuCoS.Parser; /// diff --git a/source/Parsers/YAMLParser.cs b/source/Parsers/YAMLParser.cs index a4d3646..6b186f7 100644 --- a/source/Parsers/YAMLParser.cs +++ b/source/Parsers/YAMLParser.cs @@ -1,4 +1,5 @@ using System.Text; +using FolkerKinzel.Strings; using SuCoS.Helpers; using SuCoS.Models; using YamlDotNet.Serialization; @@ -26,65 +27,71 @@ public class YAMLParser : IMetadataParser .Build(); } - /// - public (string, string) SplitFrontMatter(in string fileContent) - { - using var content = new StringReader(fileContent); - var frontMatterBuilder = new StringBuilder(); - string? line; - - while ((line = content.ReadLine()) != null && line != "---") { } - while ((line = content.ReadLine()) != null && line != "---") - { - _ = frontMatterBuilder.AppendLine(line); - } - - // Join the read lines to form the front matter - var yaml = frontMatterBuilder.ToString(); - var rawContent = content.ReadToEnd(); - - return (yaml, rawContent); - } + // /// + // public IFrontMatter ParseFrontmatterAndMarkdown( + // in string fileFullPath, + // in string fileRelativePath, + // in string fileContent + // ) + // { + // var (yaml, rawContent) = SplitFrontMatter(fileContent); + + // // Now, you can parse the YAML front matter + // var page = ParseYAML(fileFullPath, fileRelativePath, yaml, rawContent); + + // return page; + // } + + // private FrontMatter ParseYAML( + // in string fileFullPath, + // in string fileRelativePath, + // string yaml, + // in string rawContent + // ) + // { + // var frontMatter = + // deserializer.Deserialize( + // new StringReader(yaml) + // ) ?? throw new FormatException("Error parsing front matter"); + // var section = SiteHelper.GetSection(fileRelativePath); + // frontMatter.RawContent = rawContent; + // frontMatter.Section = section; + // frontMatter.SourceRelativePath = fileRelativePath; + // frontMatter.SourceFullPath = fileFullPath; + // frontMatter.Type ??= section; + // return frontMatter; + // } /// - public IFrontMatter ParseFrontmatterAndMarkdownFromFile( - in string fileFullPath, - in string? sourceContentPath = null - ) + public T Parse(string content) { - ArgumentNullException.ThrowIfNull(fileFullPath); - - string? fileContent; - string? fileRelativePath; try { - fileContent = File.ReadAllText(fileFullPath); - fileRelativePath = Path.GetRelativePath( - sourceContentPath ?? string.Empty, - fileFullPath - ); + return deserializer.Deserialize(content); } - catch (Exception ex) + catch { - throw new FileNotFoundException(fileFullPath, ex); + throw new FormatException("Error parsing front matter"); } - - return ParseFrontmatterAndMarkdown( - fileFullPath, - fileRelativePath, - fileContent - ); } /// - public IFrontMatter ParseFrontmatterAndMarkdown( - in string fileFullPath, - in string fileRelativePath, - in string fileContent - ) + public void Export(T data, string path) { - ArgumentNullException.ThrowIfNull(fileRelativePath); + var deserializer = new SerializerBuilder() + .IgnoreFields() + .ConfigureDefaultValuesHandling( + DefaultValuesHandling.OmitEmptyCollections + | DefaultValuesHandling.OmitDefaults + | DefaultValuesHandling.OmitNull) + .Build(); + var dataString = deserializer.Serialize(data); + File.WriteAllText(path, dataString); + } + /// + public (string, string) SplitFrontMatter(in string fileContent) + { using var content = new StringReader(fileContent); var frontMatterBuilder = new StringBuilder(); string? line; @@ -94,55 +101,12 @@ public class YAMLParser : IMetadataParser { _ = frontMatterBuilder.AppendLine(line); } + frontMatterBuilder.TrimEnd(); // Join the read lines to form the front matter var yaml = frontMatterBuilder.ToString(); var rawContent = content.ReadToEnd(); - // Now, you can parse the YAML front matter - var page = ParseYAML(fileFullPath, fileRelativePath, yaml, rawContent); - - return page; - } - - private FrontMatter ParseYAML( - in string fileFullPath, - in string fileRelativePath, - string yaml, - in string rawContent - ) - { - var frontMatter = - deserializer.Deserialize( - new StringReader(yaml) - ) ?? throw new FormatException("Error parsing front matter"); - var section = SiteHelper.GetSection(fileRelativePath); - frontMatter.RawContent = rawContent; - frontMatter.Section = section; - frontMatter.SourceRelativePath = fileRelativePath; - frontMatter.SourceFullPath = fileFullPath; - frontMatter.Type ??= section; - return frontMatter; - } - - /// - public T Parse(string content) - { - var data = deserializer.Deserialize(content); - return data; - } - - /// - public void Export(T data, string path) - { - var deserializer = new SerializerBuilder() - .IgnoreFields() - .ConfigureDefaultValuesHandling( - DefaultValuesHandling.OmitEmptyCollections - | DefaultValuesHandling.OmitDefaults - | DefaultValuesHandling.OmitNull) - .Build(); - var dataString = deserializer.Serialize(data); - File.WriteAllText(path, dataString); + return (yaml, rawContent); } } diff --git a/test/Models/SiteTests.cs b/test/Models/SiteTests.cs index ab3e440..9207cb4 100644 --- a/test/Models/SiteTests.cs +++ b/test/Models/SiteTests.cs @@ -17,11 +17,10 @@ public class SiteTests : TestSetup { var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fileName); var siteFullPath = Path.GetFullPath(Path.Combine(testSitesPath, testSitePathCONST01)); - - site = new Site(new GenerateOptions + site.Options = new GenerateOptions { SourceArgument = siteFullPath - }, siteSettingsMock, metadataParser, loggerMock, null); + }; // Act site.ParseAndScanSourceFiles(Path.Combine(siteFullPath, "content")); @@ -70,25 +69,25 @@ public class SiteTests : TestSetup Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page && page.IsSection).Count()); } - // [Theory] - // [InlineData(testSitePathCONST01, 5)] - // [InlineData(testSitePathCONST02, 1)] - // [InlineData(testSitePathCONST03, 13)] - // [InlineData(testSitePathCONST04, 26)] - // public void PagesReference_ShouldReturnExpectedQuantityOfPages(string sitePath, int expectedQuantity) - // { - // GenerateOptions options = new() - // { - // SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) - // }; - // site.Options = options; - - // // Act - // site.ParseAndScanSourceFiles(null); - - // // Assert - // Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page).Count()); - // } + [Theory] + [InlineData(testSitePathCONST01, 5)] + [InlineData(testSitePathCONST02, 1)] + [InlineData(testSitePathCONST03, 13)] + [InlineData(testSitePathCONST04, 26)] + public void PagesReference_ShouldReturnExpectedQuantityOfPages(string sitePath, int expectedQuantity) + { + GenerateOptions options = new() + { + SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) + }; + site.Options = options; + + // Act + site.ParseAndScanSourceFiles(null); + + // Assert + Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page).Count()); + } [Theory] [InlineData(testSitePathCONST01, 4)] @@ -101,19 +100,11 @@ public class SiteTests : TestSetup { SourceArgument = Path.GetFullPath(Path.Combine(testSitesPath, sitePath)) }; - var parser = new SuCoS.Parser.YAMLParser(); - site = new Site(options, siteSettingsMock, parser, loggerMock, null); + site.Options = options; // Act site.ParseAndScanSourceFiles(null); - foreach (var page in site.Pages) - { - // Console.WriteLine($"## {(page as Page).frontMatter.Tags} {page.Permalink}"); - } - Console.WriteLine($"{site.Pages.Count()}----"); - Console.WriteLine($"{site.OutputReferences.Values.Count()}-{expectedQuantity}----"); - // Assert Assert.Equal(expectedQuantity, site.OutputReferences.Values.Where(output => output is IPage page && page.IsPage).Count()); } diff --git a/test/Parser/YAMLParserTests.cs b/test/Parser/YAMLParserTests.cs index 09eb53e..2b24f24 100644 --- a/test/Parser/YAMLParserTests.cs +++ b/test/Parser/YAMLParserTests.cs @@ -142,7 +142,7 @@ Date: 2023/01/01 } [Fact] - public void ParseFrontmatter_ShouldThrowException_WhenInvalidYAMLSyntax() + public void ParseFrontmatter_ShouldThrowFormatException_WhenInvalidYAMLSyntax() { // Arrange const string fileContent = @"--- @@ -151,9 +151,8 @@ Title "; // Assert - Assert.Throws(() => - FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, fileContent) - ); + Assert.Throws(() => + FrontMatter.Parse(fileRelativePathCONST, fileFullPathCONST, parser, fileContent)); } [Fact] @@ -188,7 +187,6 @@ Title // Arrange var date = DateTime.Parse("2023-07-01", CultureInfo.InvariantCulture); var frontMatter = FrontMatter.Parse(string.Empty, string.Empty, parser, pageContent); - Page page = new(frontMatter, site); // Act @@ -212,44 +210,39 @@ Title Assert.Equal(2, page.TagsReference.Count); } - // [Fact] - // public void ParseFrontmatter_ShouldThrowExceptionWhenFilePathDoesNotExist2() - // { - // _ = Assert.Throws(() => parser.SplitFrontMatter(null!, null!, "fakeContent")); - // } - - // [Fact] - // public void ParseFrontmatter_ShouldHandleEmptyFileContent() - // { - // _ = Assert.Throws(() => parser.SplitFrontMatter("fakeFilePath", "/fakeFilePath", string.Empty)); - // } + [Fact] + public void FrontMatterParse_RawContentNull() + { + _ = Assert.Throws(() => FrontMatter.Parse("invalidFrontmatter", "", "fakePath", "fakePath", frontMatterParser)); + } - // [Fact] - // public void ParseYAML_ShouldThrowExceptionWhenFrontmatterIsInvalid() - // { - // _ = Assert.Throws(() => parser.SplitFrontMatter("fakeFilePath", "/fakeFilePath", "invalidFrontmatter")); - // } + [Fact] + public void ParseYAML_ShouldThrowExceptionWhenFrontmatterIsInvalid() + { + _ = Assert.Throws(() => parser.Parse("invalidFrontmatter")); + } [Fact] - public void ParseSiteSettings_ShouldReturnSiteSettings() + public void ParseYAML_ShouldSplitTheMetadata() { - // Arrange - var siteSettings = parser.Parse(siteContentCONST); + // Act + var (metadata, rawContent) = parser.SplitFrontMatter(pageContent); // Assert - Assert.NotNull(siteSettings); - Assert.Equal("My Site", siteSettings.Title); - Assert.Equal("https://www.example.com/", siteSettings.BaseURL); + Assert.Equal(pageFrontmaterCONST.TrimEnd(), metadata); + Assert.Equal(pageMarkdownCONST, rawContent); } [Fact] - public void ParseSiteSettings_ShouldReturnContent() + public void ParseSiteSettings_ShouldReturnSiteSettings() { // Arrange - var frontMatter = FrontMatter.Parse("fakeFilePath", "/fakeFilePath", parser, pageContent); + var siteSettings = parser.Parse(siteContentCONST); // Assert - Assert.Equal(pageMarkdownCONST, frontMatter.RawContent); + Assert.NotNull(siteSettings); + Assert.Equal("My Site", siteSettings.Title); + Assert.Equal("https://www.example.com/", siteSettings.BaseURL); } @@ -264,7 +257,7 @@ Title { // Arrange var siteSettings = parser.Parse(siteContentCONST); - site = new Site(generateOptionsMock, siteSettings, metadataParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettings, frontMatterParser, loggerMock, systemClockMock); // Assert Assert.NotEmpty(siteSettings.Params); diff --git a/test/TestSetup.cs b/test/TestSetup.cs index d628c37..c43fa1d 100644 --- a/test/TestSetup.cs +++ b/test/TestSetup.cs @@ -23,7 +23,7 @@ public class TestSetup protected const string testSitePathCONST07 = ".TestSites/07-theme-no-baseof-error"; protected const string testSitePathCONST08 = ".TestSites/08-theme-html"; - protected readonly IMetadataParser metadataParser = new SuCoS.Parser.YAMLParser(); + protected readonly IMetadataParser frontMatterParser = new SuCoS.Parser.YAMLParser(); protected readonly IGenerateOptions generateOptionsMock = Substitute.For(); protected readonly SiteSettings siteSettingsMock = Substitute.For(); protected readonly ILogger loggerMock = Substitute.For(); @@ -43,12 +43,12 @@ public class TestSetup public TestSetup() { _ = systemClockMock.Now.Returns(todayDate); - site = new Site(generateOptionsMock, siteSettingsMock, metadataParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettingsMock, frontMatterParser, loggerMock, systemClockMock); } public TestSetup(SiteSettings siteSettings) { _ = systemClockMock.Now.Returns(todayDate); - site = new Site(generateOptionsMock, siteSettings, metadataParser, loggerMock, systemClockMock); + site = new Site(generateOptionsMock, siteSettings, frontMatterParser, loggerMock, systemClockMock); } } -- GitLab