From a14e25bfe61625437efdf2d0543afbe09d47cb3f Mon Sep 17 00:00:00 2001 From: Martijn Laarman Date: Fri, 8 Nov 2024 12:09:16 +0100 Subject: [PATCH] initial generation diagnostics infrastructure --- docs/source/markup/substitutions.md | 2 +- src/Elastic.Markdown/BuildContext.cs | 10 +- .../Diagnostics/DiagnosticsChannel.cs | 112 ++++++++++++++++++ .../ProcessorDiagnosticExtensions.cs | 21 ++++ .../DocumentationGenerator.cs | 16 ++- src/Elastic.Markdown/IO/DocumentationSet.cs | 7 +- src/Elastic.Markdown/Myst/MarkdownParser.cs | 27 +---- src/Elastic.Markdown/Myst/ParserContext.cs | 47 ++++++++ .../Myst/Substitution/SubstitutionParser.cs | 3 + src/docs-builder/Cli/Commands.cs | 10 +- .../Diagnostics/ErrorCollector.cs | 79 ++++++++++++ src/docs-builder/Http/DocumentationWebHost.cs | 9 +- src/docs-builder/Program.cs | 5 + src/docs-builder/docs-builder.csproj | 1 + .../Directives/DirectiveBaseTests.cs | 8 +- .../Inline/InlneBaseTests.cs | 8 +- .../OutputDirectoryTests.cs | 9 +- .../SiteMap/NavigationTests.cs | 15 ++- 18 files changed, 340 insertions(+), 49 deletions(-) create mode 100644 src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs create mode 100644 src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs create mode 100644 src/Elastic.Markdown/Myst/ParserContext.cs create mode 100644 src/docs-builder/Diagnostics/ErrorCollector.cs diff --git a/docs/source/markup/substitutions.md b/docs/source/markup/substitutions.md index 4c642fe..fba0a40 100644 --- a/docs/source/markup/substitutions.md +++ b/docs/source/markup/substitutions.md @@ -9,4 +9,4 @@ Here are some variable substitutions: | Value | Source | | ------------------- | ------------ | | {{project}} | conf.py | -| {{frontmatter_key}} | Front Matter | +| {{frontmatter_key}} | Front Matter | \ No newline at end of file diff --git a/src/Elastic.Markdown/BuildContext.cs b/src/Elastic.Markdown/BuildContext.cs index c354a67..54d727f 100644 --- a/src/Elastic.Markdown/BuildContext.cs +++ b/src/Elastic.Markdown/BuildContext.cs @@ -2,12 +2,16 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions; +using Elastic.Markdown.Diagnostics; namespace Elastic.Markdown; public record BuildContext { - private readonly string? _urlPathPrefix; + public required IFileSystem ReadFileSystem { get; init; } + public required IFileSystem WriteFileSystem { get; init; } + public required DiagnosticsCollector Collector { get; init; } + public bool Force { get; init; } public string? UrlPathPrefix @@ -16,6 +20,6 @@ public string? UrlPathPrefix init => _urlPathPrefix = value; } - public required IFileSystem ReadFileSystem { get; init; } - public required IFileSystem WriteFileSystem { get; init; } + private readonly string? _urlPathPrefix; + } diff --git a/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs b/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs new file mode 100644 index 0000000..5f3526f --- /dev/null +++ b/src/Elastic.Markdown/Diagnostics/DiagnosticsChannel.cs @@ -0,0 +1,112 @@ +using System.Threading.Channels; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; + +namespace Elastic.Markdown.Diagnostics; + +public class DiagnosticsChannel +{ + private readonly Channel _channel; + private readonly CancellationTokenSource _ctxSource; + public ChannelReader Reader => _channel.Reader; + + public CancellationToken CancellationToken => _ctxSource.Token; + + public DiagnosticsChannel() + { + var options = new UnboundedChannelOptions { SingleReader = true, SingleWriter = false }; + _ctxSource = new CancellationTokenSource(); + _channel = Channel.CreateUnbounded(options); + } + + public void TryComplete(Exception? exception = null) + { + _channel.Writer.TryComplete(exception); + _ctxSource.Cancel(); + } + + public void Write(Diagnostic diagnostic) + { + var written = _channel.Writer.TryWrite(diagnostic); + if (!written) + { + //TODO + } + } +} + + +public enum Severity { Error, Warning } + +public readonly record struct Diagnostic +{ + public Severity Severity { get; init; } + public int Line { get; init; } + public int? Position { get; init; } + public string File { get; init; } + public string Message { get; init; } +} + +public interface IDiagnosticsOutput +{ + public void Write(Diagnostic diagnostic); +} + +public class LogDiagnosticOutput(ILogger logger) : IDiagnosticsOutput +{ + public void Write(Diagnostic diagnostic) + { + if (diagnostic.Severity == Severity.Error) + logger.LogError($"{diagnostic.Message} ({diagnostic.File}:{diagnostic.Line})"); + else + logger.LogWarning($"{diagnostic.Message} ({diagnostic.File}:{diagnostic.Line})"); + } +} + + +public class DiagnosticsCollector(ILoggerFactory loggerFactory, IReadOnlyCollection outputs) + : IHostedService +{ + private readonly IReadOnlyCollection _outputs = + [new LogDiagnosticOutput(loggerFactory.CreateLogger()), ..outputs]; + + public DiagnosticsChannel Channel { get; } = new(); + + private long _errors; + private long _warnings; + public long Warnings => _warnings; + public long Errors => _errors; + + public async Task StartAsync(Cancel ctx) + { + while (!Channel.CancellationToken.IsCancellationRequested) + { + while (await Channel.Reader.WaitToReadAsync(Channel.CancellationToken)) + Drain(); + } + Drain(); + + void Drain() + { + while (Channel.Reader.TryRead(out var item)) + { + IncrementSeverityCount(item); + HandleItem(item); + foreach (var output in _outputs) + output.Write(item); + } + } + } + + private void IncrementSeverityCount(Diagnostic item) + { + if (item.Severity == Severity.Error) + Interlocked.Increment(ref _errors); + else if (item.Severity == Severity.Warning) + Interlocked.Increment(ref _warnings); + } + + protected virtual void HandleItem(Diagnostic diagnostic) {} + + public virtual Task StopAsync(CancellationToken cancellationToken) => Task.CompletedTask; +} diff --git a/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs b/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs new file mode 100644 index 0000000..a5be1bc --- /dev/null +++ b/src/Elastic.Markdown/Diagnostics/ProcessorDiagnosticExtensions.cs @@ -0,0 +1,21 @@ +using Elastic.Markdown.Myst; +using Markdig.Helpers; +using Markdig.Parsers; + +namespace Elastic.Markdown.Diagnostics; + +public static class ProcessorDiagnosticExtensions +{ + public static void EmitError(this InlineProcessor processor, int line, int position, string message) + { + var d = new Diagnostic + { + Severity = Severity.Error, + File = processor.GetContext().Path.FullName, + Position = position, + Line = line, + Message = message + }; + processor.GetBuildContext().Collector.Channel.Write(d); + } +} diff --git a/src/Elastic.Markdown/DocumentationGenerator.cs b/src/Elastic.Markdown/DocumentationGenerator.cs index ceeafd8..efd9e18 100644 --- a/src/Elastic.Markdown/DocumentationGenerator.cs +++ b/src/Elastic.Markdown/DocumentationGenerator.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions; +using System.Security.Cryptography; using System.Text.Json; using System.Text.Json.Serialization; using Elastic.Markdown.IO; @@ -102,6 +103,9 @@ public async Task GenerateAll(Cancel ctx) var handledItems = 0; + + var collectTask = Task.Run(async () => await Context.Collector.StartAsync(ctx), ctx); + await Parallel.ForEachAsync(DocumentationSet.Files, ctx, async (file, token) => { if (file.SourceFile.LastWriteTimeUtc <= outputSeenChanges) @@ -122,6 +126,13 @@ await Parallel.ForEachAsync(DocumentationSet.Files, ctx, async (file, token) => if (item % 1_000 == 0) _logger.LogInformation($"Handled {handledItems} files"); }); + Context.Collector.Channel.TryComplete(); + + await GenerateDocumentationState(ctx); + + await collectTask; + await Context.Collector.StopAsync(ctx); + IFileInfo OutputFile(string relativePath) { @@ -129,12 +140,15 @@ IFileInfo OutputFile(string relativePath) return outputFile; } + } + + private async Task GenerateDocumentationState(Cancel ctx) + { var stateFile = DocumentationSet.OutputStateFile; _logger.LogInformation($"Writing documentation state {DocumentationSet.LastWrite} to {stateFile.FullName}"); var state = new OutputState { LastSeenChanges = DocumentationSet.LastWrite }; var bytes = JsonSerializer.SerializeToUtf8Bytes(state, SourceGenerationContext.Default.OutputState); await DocumentationSet.OutputPath.FileSystem.File.WriteAllBytesAsync(stateFile.FullName, bytes, ctx); - } private async Task CopyFileFsAware(DocumentationFile file, IFileInfo outputFile, Cancel ctx) diff --git a/src/Elastic.Markdown/IO/DocumentationSet.cs b/src/Elastic.Markdown/IO/DocumentationSet.cs index 810acb2..a98fa63 100644 --- a/src/Elastic.Markdown/IO/DocumentationSet.cs +++ b/src/Elastic.Markdown/IO/DocumentationSet.cs @@ -4,6 +4,7 @@ using System.Globalization; using System.IO.Abstractions; using System.Text.Json; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.Myst; namespace Elastic.Markdown.IO; @@ -19,11 +20,7 @@ public class DocumentationSet private MarkdownParser MarkdownParser { get; } - public DocumentationSet(IFileSystem fileSystem) : this(null, null, new BuildContext - { - ReadFileSystem = fileSystem, - WriteFileSystem = fileSystem - }) { } + public DocumentationSet(BuildContext context) : this(null, null, context) { } public DocumentationSet(IDirectoryInfo? sourcePath, IDirectoryInfo? outputPath, BuildContext context) { diff --git a/src/Elastic.Markdown/Myst/MarkdownParser.cs b/src/Elastic.Markdown/Myst/MarkdownParser.cs index 2913c4b..5376f41 100644 --- a/src/Elastic.Markdown/Myst/MarkdownParser.cs +++ b/src/Elastic.Markdown/Myst/MarkdownParser.cs @@ -12,32 +12,6 @@ namespace Elastic.Markdown.Myst; - -public class ParserContext : MarkdownParserContext -{ - public ParserContext(MarkdownParser markdownParser, - IFileInfo path, - YamlFrontMatter? frontMatter, - BuildContext context) - { - Parser = markdownParser; - Path = path; - FrontMatter = frontMatter; - Build = context; - - if (frontMatter?.Properties is { } props) - { - foreach (var (key, value) in props) - Properties[key] = value; - } - } - - public MarkdownParser Parser { get; } - public IFileInfo Path { get; } - public YamlFrontMatter? FrontMatter { get; } - public BuildContext Build { get; } -} - public class MarkdownParser(IDirectoryInfo sourcePath, BuildContext context) { public IDirectoryInfo SourcePath { get; } = sourcePath; @@ -46,6 +20,7 @@ public class MarkdownParser(IDirectoryInfo sourcePath, BuildContext context) public MarkdownPipeline Pipeline => new MarkdownPipelineBuilder() .EnableTrackTrivia() + .UsePreciseSourceLocation() .UseGenericAttributes() .UseEmphasisExtras(EmphasisExtraOptions.Default) .UseSoftlineBreakAsHardlineBreak() diff --git a/src/Elastic.Markdown/Myst/ParserContext.cs b/src/Elastic.Markdown/Myst/ParserContext.cs new file mode 100644 index 0000000..de2f5fe --- /dev/null +++ b/src/Elastic.Markdown/Myst/ParserContext.cs @@ -0,0 +1,47 @@ +using System.IO.Abstractions; +using Markdig; +using Markdig.Parsers; + +namespace Elastic.Markdown.Myst; + +public static class ParserContextExtensions +{ + public static BuildContext GetBuildContext(this InlineProcessor processor) => + processor.GetContext().Build; + + public static BuildContext GetBuildContext(this BlockProcessor processor) => + processor.GetContext().Build; + + public static ParserContext GetContext(this InlineProcessor processor) => + processor.Context as ParserContext + ?? throw new InvalidOperationException($"Provided context is not a {nameof(ParserContext)}"); + + public static ParserContext GetContext(this BlockProcessor processor) => + processor.Context as ParserContext + ?? throw new InvalidOperationException($"Provided context is not a {nameof(ParserContext)}"); +} + +public class ParserContext : MarkdownParserContext +{ + public ParserContext(MarkdownParser markdownParser, + IFileInfo path, + YamlFrontMatter? frontMatter, + BuildContext context) + { + Parser = markdownParser; + Path = path; + FrontMatter = frontMatter; + Build = context; + + if (frontMatter?.Properties is { } props) + { + foreach (var (key, value) in props) + Properties[key] = value; + } + } + + public MarkdownParser Parser { get; } + public IFileInfo Path { get; } + public YamlFrontMatter? FrontMatter { get; } + public BuildContext Build { get; } +} diff --git a/src/Elastic.Markdown/Myst/Substitution/SubstitutionParser.cs b/src/Elastic.Markdown/Myst/Substitution/SubstitutionParser.cs index 1b30acc..1c7c958 100644 --- a/src/Elastic.Markdown/Myst/Substitution/SubstitutionParser.cs +++ b/src/Elastic.Markdown/Myst/Substitution/SubstitutionParser.cs @@ -5,6 +5,7 @@ using System.Diagnostics; using System.Net.Mime; using System.Runtime.CompilerServices; +using Elastic.Markdown.Diagnostics; using Markdig.Helpers; using Markdig.Parsers; using Markdig.Renderers; @@ -153,6 +154,8 @@ public override bool Match(InlineProcessor processor, ref StringSlice slice) Column = column, DelimiterCount = openSticks }; + if (!found) + processor.EmitError(line + 1, column + 3 , $"Substitution key {{{key}}} is undefined"); if (processor.TrackTrivia) { diff --git a/src/docs-builder/Cli/Commands.cs b/src/docs-builder/Cli/Commands.cs index 7cf0c19..139a223 100644 --- a/src/docs-builder/Cli/Commands.cs +++ b/src/docs-builder/Cli/Commands.cs @@ -4,8 +4,10 @@ using System.IO.Abstractions; using Actions.Core.Services; using ConsoleAppFramework; +using Documentation.Builder.Diagnostics; using Documentation.Builder.Http; using Elastic.Markdown; +using Elastic.Markdown.Diagnostics; using Microsoft.Extensions.Logging; namespace Documentation.Builder.Cli; @@ -38,7 +40,7 @@ public async Task Serve(string? path = null, Cancel ctx = default) [Command("generate")] [ConsoleAppFilter] [ConsoleAppFilter] - public async Task Generate( + public async Task Generate( string? path = null, string? output = null, string? pathPrefix = null, @@ -53,10 +55,12 @@ public async Task Generate( UrlPathPrefix = pathPrefix, Force = force ?? false, ReadFileSystem = fileSystem, - WriteFileSystem = fileSystem + WriteFileSystem = fileSystem, + Collector = new ConsoleDiagnosticsCollector(logger) }; var generator = DocumentationGenerator.Create(path, output, context, logger); await generator.GenerateAll(ctx); + return context.Collector.Errors > 1 ? 1 : 0; } /// @@ -70,7 +74,7 @@ public async Task Generate( [Command("")] [ConsoleAppFilter] [ConsoleAppFilter] - public async Task GenerateDefault( + public async Task GenerateDefault( string? path = null, string? output = null, string? pathPrefix = null, diff --git a/src/docs-builder/Diagnostics/ErrorCollector.cs b/src/docs-builder/Diagnostics/ErrorCollector.cs new file mode 100644 index 0000000..ceee890 --- /dev/null +++ b/src/docs-builder/Diagnostics/ErrorCollector.cs @@ -0,0 +1,79 @@ +using System.Diagnostics.CodeAnalysis; +using System.Text; +using Cysharp.IO; +using Elastic.Markdown.Diagnostics; +using Errata; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Spectre.Console; +using Diagnostic = Elastic.Markdown.Diagnostics.Diagnostic; + +namespace Documentation.Builder.Diagnostics; + +public class FileSourceRepository : ISourceRepository +{ + public bool TryGet(string id, [NotNullWhen(true)] out Source? source) + { + using var reader = new Utf8StreamReader(id); + var text = Encoding.UTF8.GetString(reader.ReadToEndAsync().GetAwaiter().GetResult()); + source = new Source(id, text); + return true; + } +} + +public class ConsoleDiagnosticsCollector(ILoggerFactory loggerFactory) + : DiagnosticsCollector(loggerFactory, []) +{ + private readonly List _items = new(); + + private readonly ILogger _logger = + loggerFactory.CreateLogger(); + + protected override void HandleItem(Diagnostic diagnostic) => _items.Add(diagnostic); + + public override async Task StopAsync(Cancel ctx) + { + _logger.LogError("Stopping..."); + // Create a new report + var report = new Report(new FileSourceRepository()); + foreach (var item in _items) + { + var d = item.Severity switch + { + Severity.Error => + Errata.Diagnostic.Error(item.Message) + .WithLabel(new Label(item.File, new Location(item.Line, item.Position ?? 0), "bad substitution") + .WithLength(8) + .WithPriority(1) + .WithColor(Color.Red)) + + , + Severity.Warning => + Errata.Diagnostic.Warning(item.Message), + _ => Errata.Diagnostic.Info(item.Message) + }; + report.AddDiagnostic(d); + /* + report.AddDiagnostic( + Errata.Diagnostic.Error("Operator '/' cannot be applied to operands of type 'string' and 'int'") + .WithCode("CS0019") + .WithNote("Try changing the type") + .WithLabel(new Label("Demo/Files/Program.cs", new Location(15, 23), "This is of type 'int'") + .WithLength(3) + .WithPriority(1) + .WithColor(Color.Yellow)) + .WithLabel(new Label("Demo/Files/Program.cs", new Location(15, 27), "Division is not possible") + .WithPriority(3) + .WithColor(Color.Red)) + .WithLabel(new Label("Demo/Files/Program.cs", new Location(15, 29), "This is of type 'string'") + .WithLength(3) + .WithPriority(2) + .WithColor(Color.Blue))); + */ + } + // Render the report + report.Render(AnsiConsole.Console); + AnsiConsole.WriteLine(); + await Task.CompletedTask; + } +} diff --git a/src/docs-builder/Http/DocumentationWebHost.cs b/src/docs-builder/Http/DocumentationWebHost.cs index 4804dee..75fb0bf 100644 --- a/src/docs-builder/Http/DocumentationWebHost.cs +++ b/src/docs-builder/Http/DocumentationWebHost.cs @@ -2,7 +2,9 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions; +using Documentation.Builder.Diagnostics; using Elastic.Markdown; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; @@ -24,7 +26,12 @@ public DocumentationWebHost(string? path, ILoggerFactory logger, IFileSystem fil { var builder = WebApplication.CreateSlimBuilder(); var sourcePath = path != null ? fileSystem.DirectoryInfo.New(path) : null; - var context = new BuildContext { ReadFileSystem = fileSystem, WriteFileSystem = fileSystem }; + var context = new BuildContext + { + ReadFileSystem = fileSystem, + WriteFileSystem = fileSystem, + Collector = new ConsoleDiagnosticsCollector(logger) + }; builder.Services.AddSingleton(_ => new ReloadableGeneratorState(sourcePath, null, context, logger)); builder.Services.AddHostedService(); builder.Services.AddSingleton(logger); diff --git a/src/docs-builder/Program.cs b/src/docs-builder/Program.cs index 8b0233c..4d31873 100644 --- a/src/docs-builder/Program.cs +++ b/src/docs-builder/Program.cs @@ -1,9 +1,12 @@ // Licensed to Elasticsearch B.V under one or more agreements. // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information + using Actions.Core.Extensions; using ConsoleAppFramework; using Documentation.Builder.Cli; +using Documentation.Builder.Diagnostics; +using Elastic.Markdown.Diagnostics; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; @@ -23,6 +26,8 @@ c.TimestampFormat = "[yyyy-MM-ddTHH:mm:ss] "; }); }); +services.AddSingleton(); +services.AddSingleton(); await using var serviceProvider = services.BuildServiceProvider(); var logger = serviceProvider.GetRequiredService>(); diff --git a/src/docs-builder/docs-builder.csproj b/src/docs-builder/docs-builder.csproj index 3122862..3491361 100644 --- a/src/docs-builder/docs-builder.csproj +++ b/src/docs-builder/docs-builder.csproj @@ -24,6 +24,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/tests/Elastic.Markdown.Tests/Directives/DirectiveBaseTests.cs b/tests/Elastic.Markdown.Tests/Directives/DirectiveBaseTests.cs index de278bb..b05dea0 100644 --- a/tests/Elastic.Markdown.Tests/Directives/DirectiveBaseTests.cs +++ b/tests/Elastic.Markdown.Tests/Directives/DirectiveBaseTests.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions.TestingHelpers; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO; using Elastic.Markdown.Myst; using Elastic.Markdown.Myst.Directives; @@ -50,7 +51,12 @@ protected DirectiveTest([LanguageInjection("markdown")]string content) var file = FileSystem.FileInfo.New("docs/source/index.md"); var root = FileSystem.DirectoryInfo.New(Paths.Root.FullName); - var context = new BuildContext { ReadFileSystem = FileSystem, WriteFileSystem = FileSystem }; + var context = new BuildContext + { + ReadFileSystem = FileSystem, + WriteFileSystem = FileSystem, + Collector = new DiagnosticsCollector(logger, []) + }; var parser = new MarkdownParser(root, context); File = new MarkdownFile(file, root, parser, context); diff --git a/tests/Elastic.Markdown.Tests/Inline/InlneBaseTests.cs b/tests/Elastic.Markdown.Tests/Inline/InlneBaseTests.cs index 8e14474..bb8e3f9 100644 --- a/tests/Elastic.Markdown.Tests/Inline/InlneBaseTests.cs +++ b/tests/Elastic.Markdown.Tests/Inline/InlneBaseTests.cs @@ -2,6 +2,7 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions.TestingHelpers; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO; using Elastic.Markdown.Myst; using Elastic.Markdown.Myst.Directives; @@ -77,7 +78,12 @@ protected InlineTest([LanguageInjection("markdown")]string content) var file = fileSystem.FileInfo.New("docs/source/index.md"); var root = fileSystem.DirectoryInfo.New(Paths.Root.FullName); - var context = new BuildContext { ReadFileSystem = fileSystem, WriteFileSystem = fileSystem }; + var context = new BuildContext + { + ReadFileSystem = fileSystem, + WriteFileSystem = fileSystem, + Collector = new DiagnosticsCollector(logger, []) + }; var parser = new MarkdownParser(root, context); File = new MarkdownFile(file, root, parser, context); diff --git a/tests/Elastic.Markdown.Tests/OutputDirectoryTests.cs b/tests/Elastic.Markdown.Tests/OutputDirectoryTests.cs index 0a33596..dec82f1 100644 --- a/tests/Elastic.Markdown.Tests/OutputDirectoryTests.cs +++ b/tests/Elastic.Markdown.Tests/OutputDirectoryTests.cs @@ -2,10 +2,10 @@ // Elasticsearch B.V licenses this file to you under the Apache 2.0 License. // See the LICENSE file in the project root for more information using System.IO.Abstractions.TestingHelpers; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO; using FluentAssertions; using Microsoft.Extensions.Logging.Abstractions; -using Xunit; namespace Elastic.Markdown.Tests; @@ -22,7 +22,12 @@ public async Task CreatesDefaultOutputDirectory() { CurrentDirectory = Paths.Root.FullName }); - var context = new BuildContext { ReadFileSystem = fileSystem, WriteFileSystem = fileSystem }; + var context = new BuildContext + { + ReadFileSystem = fileSystem, + WriteFileSystem = fileSystem, + Collector = new DiagnosticsCollector(logger, []) + }; var set = new DocumentationSet(null, null, context); var generator = new DocumentationGenerator(set, context, logger); diff --git a/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs b/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs index 53f023c..10c23be 100644 --- a/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs +++ b/tests/Elastic.Markdown.Tests/SiteMap/NavigationTests.cs @@ -3,6 +3,7 @@ // See the LICENSE file in the project root for more information using System.IO.Abstractions; using System.IO.Abstractions.TestingHelpers; +using Elastic.Markdown.Diagnostics; using Elastic.Markdown.IO; using FluentAssertions; using Microsoft.Extensions.Logging.Abstractions; @@ -20,14 +21,18 @@ public async Task CreatesDefaultOutputDirectory() { CurrentDirectory = Paths.Root.FullName }); - - var set = new DocumentationSet(readFs); - - set.Files.Should().HaveCountGreaterThan(10); var context = new BuildContext { - Force = false, UrlPathPrefix = null, ReadFileSystem = readFs, WriteFileSystem = writeFs + Force = false, + UrlPathPrefix = null, + ReadFileSystem = readFs, + WriteFileSystem = writeFs, + Collector = new DiagnosticsCollector(logger, []) }; + + var set = new DocumentationSet(context); + + set.Files.Should().HaveCountGreaterThan(10); var generator = new DocumentationGenerator(set, context, logger); await generator.GenerateAll(default);