-
-
Notifications
You must be signed in to change notification settings - Fork 4
Add async implementations to the HtmlFormatter. #376
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
40a43b9
Added async implementations to the HtmlFormatter.
clrudolphi 298dc15
Updated CHANGELOG.md
clrudolphi db731be
Marked as obsolete the constructors of MessagesToHtmlWriter that are …
clrudolphi 5a4766f
Changes per @gasparnagy review comments.
clrudolphi 1cd8889
Merge branch 'main' into dotnet_async
mpkorstanje 5e7c77a
Merge branch 'main' into dotnet_async
mpkorstanje b30e88e
Add PR reference
mpkorstanje e267276
Remove unused code
mpkorstanje c61a2c1
Update CHANGELOG
mpkorstanje File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,23 +6,46 @@ namespace Cucumber.HtmlFormatter; | |
| public class MessagesToHtmlWriter : IDisposable | ||
| { | ||
| private StreamWriter writer; | ||
| private Func<StreamWriter, Envelope, Task> asyncStreamSerializer; | ||
| private Action<StreamWriter, Envelope> streamSerializer; | ||
| private string template; | ||
| private JsonInHtmlWriter JsonInHtmlWriter; | ||
| private bool streamClosed = false; | ||
| private bool preMessageWritten = false; | ||
| private bool firstMessageWritten = false; | ||
| private bool postMessageWritten = false; | ||
| private bool isAsyncInitialized = false; | ||
|
|
||
| [Obsolete("Cucumber.HtmlFormatter moving to async only operations. Please use the MessagesToHtmlWriter(Stream, Func<StreamWriter, Envelope, Task>) constructor", false)] | ||
| public MessagesToHtmlWriter(Stream stream, Action<StreamWriter, Envelope> streamSerializer) : this(new StreamWriter(stream), streamSerializer) | ||
| { | ||
| } | ||
| public MessagesToHtmlWriter(Stream stream, Func<StreamWriter, Envelope, Task> asyncStreamSerializer) : this(new StreamWriter(stream), asyncStreamSerializer) { } | ||
|
|
||
| [Obsolete("Cucumber.HtmlFormatter moving to async only operations. Please use the MessagesToHtmlWriter(StreamWriter, Func<StreamWriter, Envelope, Task>) constructor", false)] | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks like a deprecation. So this needs its own |
||
| public MessagesToHtmlWriter(StreamWriter writer, Action<StreamWriter, Envelope> streamSerializer) | ||
| { | ||
| this.writer = writer; | ||
| this.streamSerializer = streamSerializer; | ||
| // Create async wrapper for sync serializer | ||
| this.asyncStreamSerializer = (w, e) => | ||
| { | ||
| streamSerializer(w, e); | ||
| return Task.CompletedTask; | ||
| }; | ||
| template = GetResource("index.mustache.html"); | ||
| JsonInHtmlWriter = new JsonInHtmlWriter(writer); | ||
| isAsyncInitialized = false; | ||
| } | ||
| public MessagesToHtmlWriter(StreamWriter writer, Func<StreamWriter, Envelope, Task> asyncStreamSerializer) | ||
| { | ||
| this.writer = writer; | ||
| this.asyncStreamSerializer = asyncStreamSerializer; | ||
| // Create sync wrapper for async serializer (will block) | ||
| this.streamSerializer = (w, e) => asyncStreamSerializer(w, e).GetAwaiter().GetResult(); | ||
| template = GetResource("index.mustache.html"); | ||
| JsonInHtmlWriter = new JsonInHtmlWriter(writer); | ||
| isAsyncInitialized = true; | ||
| } | ||
|
|
||
| private void WritePreMessage() | ||
|
|
@@ -32,15 +55,35 @@ private void WritePreMessage() | |
| WriteTemplateBetween(writer, template, "{{css}}", "{{messages}}"); | ||
| } | ||
|
|
||
| private async Task WritePreMessageAsync() | ||
| { | ||
| await WriteTemplateBetweenAsync(writer, template, null, "{{css}}"); | ||
| await WriteResourceAsync(writer, "main.css"); | ||
| await WriteTemplateBetweenAsync(writer, template, "{{css}}", "{{messages}}"); | ||
| } | ||
|
|
||
| private void WritePostMessage() | ||
| { | ||
| WriteTemplateBetween(writer, template, "{{messages}}", "{{script}}"); | ||
| WriteResource(writer, "main.js"); | ||
| WriteTemplateBetween(writer, template, "{{script}}", null); | ||
| } | ||
|
|
||
| private async Task WritePostMessageAsync() | ||
| { | ||
| await WriteTemplateBetweenAsync(writer, template, "{{messages}}", "{{script}}"); | ||
| await WriteResourceAsync(writer, "main.js"); | ||
| await WriteTemplateBetweenAsync(writer, template, "{{script}}", null); | ||
| } | ||
|
|
||
| public void Write(Envelope envelope) | ||
| { | ||
| if (isAsyncInitialized) | ||
| { | ||
| // Log a warning or use other diagnostics | ||
| System.Diagnostics.Debug.WriteLine("Warning: Using synchronous Write when initialized with async serializer"); | ||
| } | ||
|
|
||
| if (streamClosed) { throw new IOException("Stream closed"); } | ||
|
|
||
| if (!preMessageWritten) | ||
|
|
@@ -62,6 +105,37 @@ public void Write(Envelope envelope) | |
| streamSerializer(JsonInHtmlWriter, envelope); | ||
| JsonInHtmlWriter.Flush(); | ||
| } | ||
| public async Task WriteAsync(Envelope envelope) | ||
| { | ||
| if (!isAsyncInitialized) | ||
| { | ||
| // Log a warning or use other diagnostics | ||
| System.Diagnostics.Debug.WriteLine("Warning: Using asynchronous WriteAsync when initialized with sync serializer"); | ||
| } | ||
|
|
||
| if (streamClosed) { throw new IOException("Stream closed"); } | ||
|
|
||
| if (!preMessageWritten) | ||
| { | ||
| await WritePreMessageAsync(); | ||
| preMessageWritten = true; | ||
| await writer.FlushAsync(); | ||
| } | ||
| if (!firstMessageWritten) | ||
| { | ||
| firstMessageWritten = true; | ||
| } | ||
| else | ||
| { | ||
| await writer.WriteAsync(","); | ||
| await writer.FlushAsync(); | ||
| } | ||
|
|
||
| // Use the synchronous serializer in an async context | ||
| await asyncStreamSerializer(JsonInHtmlWriter, envelope); | ||
| await JsonInHtmlWriter.FlushAsync(); | ||
| } | ||
|
|
||
| public void Dispose() | ||
| { | ||
| if (streamClosed) { return; } | ||
|
|
@@ -86,27 +160,68 @@ public void Dispose() | |
| streamClosed = true; | ||
| } | ||
| } | ||
|
|
||
| public async Task DisposeAsync() | ||
| { | ||
| if (streamClosed) { return; } | ||
|
|
||
| if (!preMessageWritten) | ||
| { | ||
| await WritePreMessageAsync(); | ||
| preMessageWritten = true; | ||
| } | ||
| if (!postMessageWritten) | ||
| { | ||
| await WritePostMessageAsync(); | ||
| postMessageWritten = true; | ||
| } | ||
| try | ||
| { | ||
| await writer.FlushAsync(); | ||
| writer.Close(); | ||
| } | ||
| finally | ||
| { | ||
| streamClosed = true; | ||
| } | ||
| } | ||
|
|
||
| private void WriteResource(StreamWriter writer, string v) | ||
| { | ||
| var resource = GetResource(v); | ||
| writer.Write(resource); | ||
| } | ||
|
|
||
| private async Task WriteResourceAsync(StreamWriter writer, string v) | ||
| { | ||
| var resource = GetResource(v); | ||
| await writer.WriteAsync(resource); | ||
| } | ||
| private void WriteTemplateBetween(StreamWriter writer, string template, string? begin, string? end) | ||
| { | ||
| int beginIndex = begin == null ? 0 : template.IndexOf(begin) + begin.Length; | ||
| int endIndex = end == null ? template.Length : template.IndexOf(end); | ||
| int lengthToWrite = endIndex - beginIndex; | ||
| int beginIndex, lengthToWrite; | ||
| CalculateBeginAndLength(template, begin, end, out beginIndex, out lengthToWrite); | ||
| writer.Write(template.Substring(beginIndex, lengthToWrite)); | ||
| } | ||
|
|
||
| private static void CalculateBeginAndLength(string template, string? begin, string? end, out int beginIndex, out int lengthToWrite) | ||
| { | ||
| beginIndex = begin == null ? 0 : template.IndexOf(begin) + begin.Length; | ||
| int endIndex = end == null ? template.Length : template.IndexOf(end); | ||
| lengthToWrite = endIndex - beginIndex; | ||
| } | ||
|
|
||
| private async Task WriteTemplateBetweenAsync(StreamWriter writer, string template, string? begin, string? end) | ||
| { | ||
| int beginIndex, lengthToWrite; | ||
| CalculateBeginAndLength(template, begin, end, out beginIndex, out lengthToWrite); | ||
| await writer.WriteAsync(template.Substring(beginIndex, lengthToWrite)); | ||
| } | ||
| private string GetResource(string name) | ||
| { | ||
| var assembly = typeof(MessagesToHtmlWriter).Assembly; | ||
| var resourceStream = assembly.GetManifestResourceStream("Cucumber.HtmlFormatter.Resources." + name); | ||
| var resource = new StreamReader(resourceStream).ReadToEnd(); | ||
| return resource; | ||
| } | ||
|
|
||
|
|
||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've changed this to added. It doesn't look like anything was removed. Is that correct w.r.t the guidance on http://semver.org?