Skip to content
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

Release of new minor version v1.22 #1163

Merged
merged 27 commits into from
Jul 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fb48052
Set version to '1.22-preview'
bUnitBot Jul 2, 2023
3b6e180
Merge branch 'release/v1.21'
bUnitBot Jul 2, 2023
90fd5fc
Merge branch 'stable'
bUnitBot Jul 2, 2023
ef86f1c
chore: upgrade xunit and SonarAnalyzer.CSharp packages
egil Jul 7, 2023
c34880d
fix: Change all bUnit services registration from singleton to scoped
egil Jul 7, 2023
0696817
ci: run sample doc verification
egil Jul 7, 2023
70c1338
feat: Add target sdk for template (#1152)
linkdotnet Jul 9, 2023
b6574ac
fix: AssertNoUnhandledExceptions, SetDirectParameters, and DisposeCom…
egil Jun 29, 2023
88655c1
fix: prevent recursion when determining if rendered component changed
egil Jun 29, 2023
fb40d20
fix: improve logging output
egil Jun 30, 2023
9cdc156
feat: improve event dispatching logging
egil Jul 1, 2023
d51a1b3
fix: removed unused method from RenderEvent
egil Jul 1, 2023
967c6a1
fix: handle exceptions in the same way as DispatchEventAsync
egil Jul 1, 2023
af3de56
chore: explained code
egil Jul 1, 2023
c8508f7
refactor: renderEvent.GetStatus -> renderEvent.GetOrCreateStatus
egil Jul 11, 2023
e766065
fix: ensure dispose checks are performed before and after entering re…
egil Jul 11, 2023
b7c84ed
fix: increment TestRenderer.RenderCount when applying render event
egil Jul 11, 2023
449309e
reverse version upgrade of shouldly in bunit.web.testcomponents.tests
egil Jul 11, 2023
dced948
build(deps): Bump dotnet/nbgv from 0.4.0 to 0.4.1 (#1156)
dependabot[bot] Jul 12, 2023
4353f88
fix: handle duplicated entries in RenderBatch.UpdatedComponents
egil Jul 13, 2023
fd85b8d
Revert "fix: Change all bUnit services registration from singleton to…
egil Jul 13, 2023
4cb7458
fix: remove capture and dispatch to user sync context
egil Jul 15, 2023
ffd6fa7
chore: Added test for MarkupMatches to render fragment when renderer …
linkdotnet Jul 15, 2023
76fd92f
fix: New up renderer for markup matches (#1160)
linkdotnet Jul 23, 2023
8633b2f
build(deps): Bump SonarAnalyzer.CSharp from 9.5.0.73987 to 9.6.0.74858
dependabot[bot] Jul 25, 2023
faec85d
docs: update changelog with fixes in next release
egil Jul 28, 2023
0c1147b
Set version to '1.22'
bUnitBot Jul 28, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/docs-deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
git config --global commit.gpgsign true

- name: ⚙️ Setup GIT versioning
uses: dotnet/nbgv@v0.4.0
uses: dotnet/nbgv@v0.4.1
with:
setAllVars: true

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/prepare-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ jobs:
git config --global commit.gpgsign true

- name: ⚙️ Setup GIT versioning
uses: dotnet/nbgv@v0.4.0
uses: dotnet/nbgv@v0.4.1
with:
setAllVars: true

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-preview.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
fetch-depth: 0

- name: ⚙️ Setup GIT versioning
uses: dotnet/nbgv@v0.4.0
uses: dotnet/nbgv@v0.4.1

- name: ⚙️ Setup dotnet versions
uses: actions/setup-dotnet@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
git config --global commit.gpgsign true

- name: ⚙️ Setup GIT versioning
uses: dotnet/nbgv@v0.4.0
uses: dotnet/nbgv@v0.4.1
with:
setAllVars: true

Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/verification.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ jobs:
echo "TERM=xterm" >> $GITHUB_ENV

- name: ⚙️ Setup GIT versioning
uses: dotnet/nbgv@v0.4.0
uses: dotnet/nbgv@v0.4.1
with:
setAllVars: true

Expand All @@ -72,6 +72,9 @@ jobs:
run: |
dotnet test --filter Category!=async -c release

- name: 🧪 Run sample unit tests
run: dotnet test -c release docs/samples/samples.sln

- name: 📛 Upload hang- and crash-dumps on test failure
if: failure()
uses: actions/upload-artifact@v3
Expand Down
402 changes: 207 additions & 195 deletions CHANGELOG.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<!-- Shared code analyzers used for all projects in the solution -->
<ItemGroup Label="Code Analyzers">
<PackageReference Include="AsyncFixer" Version="1.6.0" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.4.0.72892" PrivateAssets="All" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="9.6.0.74858" PrivateAssets="All" />
</ItemGroup>

<ItemGroup Label="Implicit usings"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ namespace Bunit.Extensions.WaitForHelpers;
internal static class WaitForHelperLoggerExtensions
{
private static readonly Action<ILogger, int, Exception?> CheckingWaitCondition
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(1, "OnAfterRender"), "Checking the wait condition for component {Id}.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(1, "CheckingWaitCondition"), "Checking the wait condition for component {Id}.");

private static readonly Action<ILogger, int, Exception?> CheckCompleted
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(2, "OnAfterRender"), "The check completed successfully for component {Id}.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(2, "CheckCompleted"), "The check completed successfully for component {Id}.");

private static readonly Action<ILogger, int, Exception?> CheckFailed
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(3, "OnAfterRender"), "The check failed for component {Id}.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(3, "CheckFailed"), "The check failed for component {Id}.");

private static readonly Action<ILogger, int, Exception> CheckThrow
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(4, "OnAfterRender"), "The checker for component {Id} throw an exception.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(4, "CheckThrow"), "The checker for component {Id} throw an exception.");

private static readonly Action<ILogger, int, Exception?> WaiterTimedOut
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "OnTimeout"), "The waiter for component {Id} timed out.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(10, "WaiterTimedOut"), "The waiter for component {Id} timed out.");

private static readonly Action<ILogger, int, Exception?> WaiterDisposed
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(20, "OnTimeout"), "The waiter for component {Id} disposed.");
= LoggerMessage.Define<int>(LogLevel.Debug, new EventId(20, "WaiterDisposed"), "The waiter for component {Id} disposed.");

internal static void LogCheckingWaitCondition<T>(this ILogger<WaitForHelper<T>> logger, int componentId)
{
Expand Down
120 changes: 41 additions & 79 deletions src/bunit.core/Rendering/RenderEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,15 @@ namespace Bunit.Rendering;
/// </summary>
public sealed class RenderEvent
{
private readonly RenderBatch renderBatch;
private readonly Dictionary<int, Status> statuses = new();

internal IReadOnlyDictionary<int, Status> Statuses => statuses;

/// <summary>
/// Gets a collection of <see cref="ArrayRange{RenderTreeFrame}"/>, accessible via the ID
/// of the component they are created by.
/// </summary>
public RenderTreeFrameDictionary Frames { get; }

/// <summary>
/// Initializes a new instance of the <see cref="RenderEvent"/> class.
/// </summary>
/// <param name="renderBatch">The <see cref="RenderBatch"/> update from the render event.</param>
/// <param name="frames">The <see cref="RenderTreeFrameDictionary"/> from the current render.</param>
internal RenderEvent(RenderBatch renderBatch, RenderTreeFrameDictionary frames)
{
this.renderBatch = renderBatch;
Frames = frames;
}
public RenderTreeFrameDictionary Frames { get; } = new();

/// <summary>
/// Gets the render status for a <paramref name="renderedComponent"/>.
Expand All @@ -34,86 +25,57 @@ internal RenderEvent(RenderBatch renderBatch, RenderTreeFrameDictionary frames)
if (renderedComponent is null)
throw new ArgumentNullException(nameof(renderedComponent));

var result = (Rendered: false, Changed: false, Disposed: false);
return statuses.TryGetValue(renderedComponent.ComponentId, out var status)
? (status.Rendered, status.Changed, status.Disposed)
: (Rendered: false, Changed: false, Disposed: false);
}

if (DidComponentDispose(renderedComponent))
{
result.Disposed = true;
}
else
internal Status GetOrCreateStatus(int componentId)
{
if (!statuses.TryGetValue(componentId, out var status))
{
(result.Rendered, result.Changed) = GetRenderAndChangeStatus(renderedComponent);
status = new();
statuses[componentId] = status;
}
return status;
}

return result;
internal void SetDisposed(int componentId)
{
GetOrCreateStatus(componentId).Disposed = true;
}

private bool DidComponentDispose(IRenderedFragmentBase renderedComponent)
internal void SetUpdated(int componentId, bool hasChanges)
{
for (var i = 0; i < renderBatch.DisposedComponentIDs.Count; i++)
{
if (renderBatch.DisposedComponentIDs.Array[i].Equals(renderedComponent.ComponentId))
{
return true;
}
}
var status = GetOrCreateStatus(componentId);
status.Rendered = true;
status.Changed = status.Changed || hasChanges;
}

return false;
internal void SetUpdatedApplied(int componentId)
{
GetOrCreateStatus(componentId).UpdatesApplied = true;
}

/// <summary>
/// This method determines if the <paramref name="renderedComponent"/> or any of the
/// components underneath it in the render tree rendered and whether they they changed
/// their render tree during render.
///
/// It does this by getting the status from the <paramref name="renderedComponent"/>,
/// then from all its children, using a recursive pattern, where the internal methods
/// GetStatus and GetStatusFromChildren call each other until there are no more children,
/// or both a render and a change is found.
/// </summary>
private (bool Rendered, bool HasChanges) GetRenderAndChangeStatus(IRenderedFragmentBase renderedComponent)
internal void AddFrames(int componentId, ArrayRange<RenderTreeFrame> frames)
{
var result = (Rendered: false, HasChanges: false);
Frames.Add(componentId, frames);
GetOrCreateStatus(componentId).FramesLoaded = true;
}

GetStatus(renderedComponent.ComponentId);
internal record class Status
{
public bool Rendered { get; set; }

return result;
public bool Changed { get; set; }

void GetStatus(int componentId)
{
for (var i = 0; i < renderBatch.UpdatedComponents.Count; i++)
{
ref var update = ref renderBatch.UpdatedComponents.Array[i];
if (update.ComponentId == componentId)
{
result.Rendered = true;
result.HasChanges = update.Edits.Count > 0;
break;
}
}

if (!result.HasChanges)
{
GetStatusFromChildren(componentId);
}
}
public bool Disposed { get; set; }

void GetStatusFromChildren(int componentId)
{
var frames = Frames[componentId];
for (var i = 0; i < frames.Count; i++)
{
ref var frame = ref frames.Array[i];
if (frame.FrameType == RenderTreeFrameType.Component)
{
GetStatus(frame.ComponentId);

if (result.HasChanges)
{
break;
}
}
}
}
public bool UpdatesApplied { get; set; }

public bool FramesLoaded { get; set; }

public bool UpdateNeeded => Rendered || Changed;
}
}

Loading
Loading