From 8e222e2a0d68873208a4e8b018fcef209407d463 Mon Sep 17 00:00:00 2001 From: bUnit bot Date: Tue, 12 Nov 2024 20:34:18 +0000 Subject: [PATCH 1/9] Set version to '1.37-preview' --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 2aa22fb3e..4b460b45b 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.36-preview", + "version": "1.37-preview", "assemblyVersion": { "precision": "revision" }, From 9197071a2ea65094a58e7d780b874b76550a41d2 Mon Sep 17 00:00:00 2001 From: Simon Cropp Date: Sat, 14 Dec 2024 02:33:40 +1100 Subject: [PATCH 2/9] refactor: remove static uses of PrettyMarkupFormatter (#1609) PrettyMarkupFormatter is not thread safe https://github.com/VerifyTests/Verify.Bunit/issues/60 --- src/bunit.web/Diffing/DiffMarkupFormatter.cs | 1 + src/bunit.web/Extensions/NodePrintExtensions.cs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/bunit.web/Diffing/DiffMarkupFormatter.cs b/src/bunit.web/Diffing/DiffMarkupFormatter.cs index ccb033627..4feffd455 100644 --- a/src/bunit.web/Diffing/DiffMarkupFormatter.cs +++ b/src/bunit.web/Diffing/DiffMarkupFormatter.cs @@ -16,6 +16,7 @@ public class DiffMarkupFormatter : PrettyMarkupFormatter, IMarkupFormatter /// The is not thread safe, so using this singleton /// instance to format elements may not result in the desired effect. /// + [Obsolete("This instance is not thread safe, use a new instance instead.")] public static new readonly DiffMarkupFormatter Instance = new(); /// diff --git a/src/bunit.web/Extensions/NodePrintExtensions.cs b/src/bunit.web/Extensions/NodePrintExtensions.cs index c54924824..d113d2642 100644 --- a/src/bunit.web/Extensions/NodePrintExtensions.cs +++ b/src/bunit.web/Extensions/NodePrintExtensions.cs @@ -109,6 +109,7 @@ public static string ToMarkupElementOnly(this IElement element) if (element is null) throw new ArgumentNullException(nameof(element)); + var diffMarkupFormatter = new DiffMarkupFormatter(); var result = new StringBuilder(); result.Append(Symbols.LessThan); @@ -120,7 +121,7 @@ public static string ToMarkupElementOnly(this IElement element) foreach (var attribute in element.Attributes) { - result.Append(' ').Append(DiffMarkupFormatter.Instance.ConvertToString(attribute)); + result.Append(' ').Append(diffMarkupFormatter.ConvertToString(attribute)); } if (element.HasChildNodes) From 3111b1de24637c4647f7984c45899efdd7cf338d Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Fri, 1 Nov 2024 16:18:26 +0100 Subject: [PATCH 3/9] feat: Add RendererInfo support for .net9 --- CHANGELOG.md | 3 ++ src/bunit.core/Rendering/ITestRenderer.cs | 7 ++++ .../Rendering/MissingRendererInfoException.cs | 33 +++++++++++++++++++ src/bunit.core/Rendering/TestRenderer.cs | 15 +++++++++ .../Rendering/RendererInfoTests.cs | 28 ++++++++++++++++ .../RenderModes/RendererInfoComponent.cs | 20 +++++++++++ 6 files changed, 106 insertions(+) create mode 100644 src/bunit.core/Rendering/MissingRendererInfoException.cs create mode 100644 tests/bunit.core.tests/Rendering/RendererInfoTests.cs create mode 100644 tests/bunit.testassets/RenderModes/RendererInfoComponent.cs diff --git a/CHANGELOG.md b/CHANGELOG.md index 1e9ab3753..ecf041582 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ All notable changes to **bUnit** will be documented in this file. The project ad ## [Unreleased] +### Added +- Added support for `RendererInfo` (`.net9.0`). + ## [1.36.0] - 2024-11-12 ### Added diff --git a/src/bunit.core/Rendering/ITestRenderer.cs b/src/bunit.core/Rendering/ITestRenderer.cs index 50f8d3e72..cfd855d33 100644 --- a/src/bunit.core/Rendering/ITestRenderer.cs +++ b/src/bunit.core/Rendering/ITestRenderer.cs @@ -78,4 +78,11 @@ IReadOnlyList> FindComponents(IRe /// Disposes all components rendered by the . /// void DisposeComponents(); + +#if NET9_0_OR_GREATER + /// + /// Sets the for the renderer. + /// + void SetRendererInfo(RendererInfo? rendererInfo); +#endif } diff --git a/src/bunit.core/Rendering/MissingRendererInfoException.cs b/src/bunit.core/Rendering/MissingRendererInfoException.cs new file mode 100644 index 000000000..147a254fe --- /dev/null +++ b/src/bunit.core/Rendering/MissingRendererInfoException.cs @@ -0,0 +1,33 @@ +#if NET9_0_OR_GREATER +namespace Bunit.Rendering; + +/// +/// Represents an exception that is thrown when a component under test is trying to access the 'RendererInfo' property, which has not been specified. +/// +public sealed class MissingRendererInfoException : Exception +{ + /// + /// Initializes a new instance of the class. + /// + public MissingRendererInfoException() + : base(""" + A component under test is trying to access the 'RendererInfo' property, which has not been specified. Set it via TestContext.Renderer.SetRendererInfo. + + For example: + + public class SomeTestClass : TestContext + { + [Fact] + public void SomeTestCase() + { + Renderer.SetRendererInfo(new RendererInfo("Server", true)); + ... + } + } + + The four built in render names are 'Static', 'Server', 'WebAssembly', and 'WebView'. + """) + { + } +} +#endif diff --git a/src/bunit.core/Rendering/TestRenderer.cs b/src/bunit.core/Rendering/TestRenderer.cs index 61d4deecf..34d2377f7 100644 --- a/src/bunit.core/Rendering/TestRenderer.cs +++ b/src/bunit.core/Rendering/TestRenderer.cs @@ -64,6 +64,21 @@ private bool IsBatchInProgress /// internal int RenderCount { get; private set; } +#if NET9_0_OR_GREATER + private RendererInfo? rendererInfo; + + /// + [SuppressMessage("Design", "CA1065:Do not raise exceptions in unexpected locations", Justification = "The exception is raised to guide users.")] + protected override RendererInfo RendererInfo => rendererInfo ?? throw new MissingRendererInfoException(); + + /// + public void SetRendererInfo(RendererInfo? rendererInfo) + { + this.rendererInfo = rendererInfo; + } + +#endif + #if NETSTANDARD /// /// Initializes a new instance of the class. diff --git a/tests/bunit.core.tests/Rendering/RendererInfoTests.cs b/tests/bunit.core.tests/Rendering/RendererInfoTests.cs new file mode 100644 index 000000000..cdccb3b58 --- /dev/null +++ b/tests/bunit.core.tests/Rendering/RendererInfoTests.cs @@ -0,0 +1,28 @@ +#if NET9_0_OR_GREATER +using Bunit.TestAssets.RenderModes; + +namespace Bunit.Rendering; + +public class RendererInfoTests : TestContext +{ + [Fact(DisplayName = "TestRenderer provides RendererInfo")] + public void Test001() + { + Renderer.SetRendererInfo(new RendererInfo("Server", true)); + var cut = RenderComponent(); + + cut.MarkupMatches(""" +

Is interactive: True

+

Rendermode: Server

+ """); + } + + [Fact(DisplayName = "Renderer throws exception if RendererInfo is not specified")] + public void Test002() + { + Action act = () => RenderComponent(); + + act.ShouldThrow(); + } +} +#endif \ No newline at end of file diff --git a/tests/bunit.testassets/RenderModes/RendererInfoComponent.cs b/tests/bunit.testassets/RenderModes/RendererInfoComponent.cs new file mode 100644 index 000000000..9393ab3eb --- /dev/null +++ b/tests/bunit.testassets/RenderModes/RendererInfoComponent.cs @@ -0,0 +1,20 @@ +#if NET9_0_OR_GREATER + +namespace Bunit.TestAssets.RenderModes; + +public class RendererInfoComponent : ComponentBase +{ + protected override void BuildRenderTree(RenderTreeBuilder builder) + { + builder.OpenElement(0, "p"); + builder.AddContent(1, "Is interactive: "); + builder.AddContent(2, RendererInfo.IsInteractive); + builder.CloseElement(); + + builder.OpenElement(3, "p"); + builder.AddContent(4, "Rendermode: "); + builder.AddContent(5, RendererInfo.Name); + builder.CloseElement(); + } +} +#endif \ No newline at end of file From b5bcbd28e1c10e961bec606d4777498fecead815 Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Fri, 1 Nov 2024 17:06:07 +0100 Subject: [PATCH 4/9] feat: Enable RenderMode cascading to the Component --- CHANGELOG.md | 2 +- src/bunit.core/Rendering/TestRenderer.cs | 21 ++++++ .../Rendering/RenderModeTests.cs | 73 +++++++++++++++++++ .../Rendering/RendererInfoTests.cs | 28 ------- .../ComponentWithServerRenderMode.razor | 15 ++++ .../ComponentWithWebAssemblyRenderMode.razor | 15 ++++ .../ComponentWithoutRenderMode.razor | 14 ++++ 7 files changed, 139 insertions(+), 29 deletions(-) create mode 100644 tests/bunit.core.tests/Rendering/RenderModeTests.cs delete mode 100644 tests/bunit.core.tests/Rendering/RendererInfoTests.cs create mode 100644 tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor create mode 100644 tests/bunit.testassets/RenderModes/ComponentWithWebAssemblyRenderMode.razor create mode 100644 tests/bunit.testassets/RenderModes/ComponentWithoutRenderMode.razor diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf041582..b55950017 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ All notable changes to **bUnit** will be documented in this file. The project ad ## [Unreleased] ### Added -- Added support for `RendererInfo` (`.net9.0`). +- Added support for `RendererInfo` and `AssignedRenderMode` (`.net9.0`). ## [1.36.0] - 2024-11-12 diff --git a/src/bunit.core/Rendering/TestRenderer.cs b/src/bunit.core/Rendering/TestRenderer.cs index 34d2377f7..df41b817a 100644 --- a/src/bunit.core/Rendering/TestRenderer.cs +++ b/src/bunit.core/Rendering/TestRenderer.cs @@ -241,6 +241,27 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, } #endif +#if NET9_0_OR_GREATER + /// + protected override IComponentRenderMode? GetComponentRenderMode(IComponent component) + { + ArgumentNullException.ThrowIfNull(component); + + var renderModeAttribute = component.GetType() + .GetCustomAttribute(); + + if (renderModeAttribute is not null) + { + return renderModeAttribute.Mode; + } + + var parentComponentState = GetComponentState(component).ParentComponentState; + return parentComponentState is not null + ? GetComponentRenderMode(parentComponentState.Component) + : null; + } +#endif + /// internal Task SetDirectParametersAsync(IRenderedFragmentBase renderedComponent, ParameterView parameters) { diff --git a/tests/bunit.core.tests/Rendering/RenderModeTests.cs b/tests/bunit.core.tests/Rendering/RenderModeTests.cs new file mode 100644 index 000000000..352da9dec --- /dev/null +++ b/tests/bunit.core.tests/Rendering/RenderModeTests.cs @@ -0,0 +1,73 @@ +#if NET9_0_OR_GREATER +using Bunit.TestAssets.RenderModes; + +namespace Bunit.Rendering; + +public class RenderModeTests : TestContext +{ + [Fact(DisplayName = "TestRenderer provides RendererInfo")] + public void Test001() + { + Renderer.SetRendererInfo(new RendererInfo("Server", true)); + var cut = RenderComponent(); + + cut.MarkupMatches(""" +

Is interactive: True

+

Rendermode: Server

+ """); + } + + [Fact(DisplayName = "Renderer throws exception if RendererInfo is not specified")] + public void Test002() + { + Action act = () => RenderComponent(); + + act.ShouldThrow(); + } + + [Fact(DisplayName = "Renderer should set the RenderModeAttribute on the component")] + public void Test003() + { + var cut = RenderComponent(); + + cut.MarkupMatches("
Assigned render mode: InteractiveServerRenderMode
"); + } + + [Fact(DisplayName = "The AssignedRenderMode is based on the RenderModeAttribute in the component hierarchy where parent component has no RenderMode")] + public void Test004() + { + var cut = RenderComponent( + c => c.AddChildContent()); + + cut.MarkupMatches(""" +
Parent assigned render mode:
+
Assigned render mode: InteractiveWebAssemblyRenderMode
+ """); + } + + [Fact(DisplayName = "Parent and child render mode is specified")] + public void Test005() + { + var cut = RenderComponent( + c => c.AddChildContent()); + + cut.MarkupMatches(""" +
Parent assigned render mode: InteractiveWebAssemblyRenderMode
+
Assigned render mode: InteractiveServerRenderMode
+ """); + } + + [Fact(DisplayName = "Parent and child render mode is not specified")] + public void Test006() + { + var cut = RenderComponent( + c => c.AddChildContent()); + + cut.MarkupMatches(""" +
Parent assigned render mode:
+
Assigned render mode:
+ """); + + } +} +#endif \ No newline at end of file diff --git a/tests/bunit.core.tests/Rendering/RendererInfoTests.cs b/tests/bunit.core.tests/Rendering/RendererInfoTests.cs deleted file mode 100644 index cdccb3b58..000000000 --- a/tests/bunit.core.tests/Rendering/RendererInfoTests.cs +++ /dev/null @@ -1,28 +0,0 @@ -#if NET9_0_OR_GREATER -using Bunit.TestAssets.RenderModes; - -namespace Bunit.Rendering; - -public class RendererInfoTests : TestContext -{ - [Fact(DisplayName = "TestRenderer provides RendererInfo")] - public void Test001() - { - Renderer.SetRendererInfo(new RendererInfo("Server", true)); - var cut = RenderComponent(); - - cut.MarkupMatches(""" -

Is interactive: True

-

Rendermode: Server

- """); - } - - [Fact(DisplayName = "Renderer throws exception if RendererInfo is not specified")] - public void Test002() - { - Action act = () => RenderComponent(); - - act.ShouldThrow(); - } -} -#endif \ No newline at end of file diff --git a/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor b/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor new file mode 100644 index 000000000..3ce1d35a0 --- /dev/null +++ b/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor @@ -0,0 +1,15 @@ +@{ +#if NET9_0_OR_GREATER +} + +@rendermode Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveServer +
@(ChildContent is not null ? "Parent assigned" : "Assigned") render mode: @AssignedRenderMode?.GetType().Name
+@ChildContent + +@code { + [Parameter] public RenderFragment? ChildContent { get; set; } +} + +@{ +#endif +} \ No newline at end of file diff --git a/tests/bunit.testassets/RenderModes/ComponentWithWebAssemblyRenderMode.razor b/tests/bunit.testassets/RenderModes/ComponentWithWebAssemblyRenderMode.razor new file mode 100644 index 000000000..af0888317 --- /dev/null +++ b/tests/bunit.testassets/RenderModes/ComponentWithWebAssemblyRenderMode.razor @@ -0,0 +1,15 @@ +@{ +#if NET9_0_OR_GREATER +} + +@rendermode Microsoft.AspNetCore.Components.Web.RenderMode.InteractiveWebAssembly +
@(ChildContent is not null ? "Parent assigned" : "Assigned") render mode: @AssignedRenderMode?.GetType().Name
+@ChildContent + +@code { + [Parameter] public RenderFragment? ChildContent { get; set; } +} + +@{ +#endif +} \ No newline at end of file diff --git a/tests/bunit.testassets/RenderModes/ComponentWithoutRenderMode.razor b/tests/bunit.testassets/RenderModes/ComponentWithoutRenderMode.razor new file mode 100644 index 000000000..6d5f7f9b7 --- /dev/null +++ b/tests/bunit.testassets/RenderModes/ComponentWithoutRenderMode.razor @@ -0,0 +1,14 @@ +@{ +#if NET9_0_OR_GREATER +} + +
@(ChildContent is not null ? "Parent assigned" : "Assigned") render mode: @AssignedRenderMode?.GetType().Name
+@ChildContent + +@code { + [Parameter] public RenderFragment? ChildContent { get; set; } +} + +@{ +#endif +} \ No newline at end of file From 244680cd96318ab8b71e8dc369917ec3f88e567e Mon Sep 17 00:00:00 2001 From: Egil Hansen Date: Fri, 15 Nov 2024 16:29:35 +0000 Subject: [PATCH 5/9] fix: support finding render modes specified via @rendermode directive --- .../Rendering/RenderModeMisMatchException.cs | 22 +++ src/bunit.core/Rendering/TestRenderer.cs | 55 +++++-- .../Rendering/RenderModeTests.cs | 73 --------- .../Rendering/RenderModeTests.razor | 142 ++++++++++++++++++ ...omponentThatPrintsAssignedRenderMode.razor | 9 ++ .../ComponentWithChildContent.razor | 6 + .../ComponentWithServerRenderMode.razor | 2 +- .../RenderModes/SectionOutletComponent.razor | 12 ++ 8 files changed, 238 insertions(+), 83 deletions(-) create mode 100644 src/bunit.core/Rendering/RenderModeMisMatchException.cs delete mode 100644 tests/bunit.core.tests/Rendering/RenderModeTests.cs create mode 100644 tests/bunit.core.tests/Rendering/RenderModeTests.razor create mode 100644 tests/bunit.testassets/RenderModes/ComponentThatPrintsAssignedRenderMode.razor create mode 100644 tests/bunit.testassets/RenderModes/ComponentWithChildContent.razor create mode 100644 tests/bunit.testassets/RenderModes/SectionOutletComponent.razor diff --git a/src/bunit.core/Rendering/RenderModeMisMatchException.cs b/src/bunit.core/Rendering/RenderModeMisMatchException.cs new file mode 100644 index 000000000..8187988e3 --- /dev/null +++ b/src/bunit.core/Rendering/RenderModeMisMatchException.cs @@ -0,0 +1,22 @@ +#if NET9_0_OR_GREATER +namespace Bunit.Rendering; + +/// +/// Represents an exception that is thrown when a component under test has mismatching render modes assigned between parent and child components. +/// +public sealed class RenderModeMisMatchException : Exception +{ + /// + /// Initializes a new instance of the class. + /// + public RenderModeMisMatchException() + : base(""" + A component under test has mismatching render modes assigned between parent and child components. + Ensure that the render mode of the parent component matches the render mode of the child component. + Learn more about render modes at https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0#render-mode-propagation. + """) + { + HelpLink = "https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0#render-mode-propagation"; + } +} +#endif diff --git a/src/bunit.core/Rendering/TestRenderer.cs b/src/bunit.core/Rendering/TestRenderer.cs index df41b817a..f26e77fd0 100644 --- a/src/bunit.core/Rendering/TestRenderer.cs +++ b/src/bunit.core/Rendering/TestRenderer.cs @@ -1,7 +1,7 @@ -using Microsoft.Extensions.Logging; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.ExceptionServices; +using Microsoft.Extensions.Logging; namespace Bunit.Rendering; @@ -247,18 +247,55 @@ protected override IComponent ResolveComponentForRenderMode(Type componentType, { ArgumentNullException.ThrowIfNull(component); - var renderModeAttribute = component.GetType() - .GetCustomAttribute(); + // Search from the current component all the way up the render tree. + // All components must have the same render mode specified (or none at all). + // Return the render mode that is found after checking the full tree. + return GetAndValidateRenderMode(component, childRenderMode: null); - if (renderModeAttribute is not null) + IComponentRenderMode? GetAndValidateRenderMode(IComponent component, IComponentRenderMode? childRenderMode) { - return renderModeAttribute.Mode; + var componentState = GetComponentState(component); + var renderMode = GetRenderModeForComponent(componentState); + + if (childRenderMode is not null && renderMode is not null && childRenderMode != renderMode) + { + throw new RenderModeMisMatchException(); + } + + return componentState.ParentComponentState is null + ? renderMode ?? childRenderMode + : GetAndValidateRenderMode(componentState.ParentComponentState.Component, renderMode ?? childRenderMode); } - var parentComponentState = GetComponentState(component).ParentComponentState; - return parentComponentState is not null - ? GetComponentRenderMode(parentComponentState.Component) - : null; + IComponentRenderMode? GetRenderModeForComponent(ComponentState componentState) + { + var renderModeAttribute = componentState.Component.GetType().GetCustomAttribute(); + if (renderModeAttribute is { Mode: not null }) + { + return renderModeAttribute.Mode; + } + + if (componentState.ParentComponentState is not null) + { + var parentFrames = GetCurrentRenderTreeFrames(componentState.ParentComponentState.ComponentId); + var foundComponentStart = false; + for (var i = 0; i < parentFrames.Count; i++) + { + ref var frame = ref parentFrames.Array[i]; + + if (frame.FrameType is RenderTreeFrameType.Component) + { + foundComponentStart = frame.ComponentId == componentState.ComponentId; + } + else if (foundComponentStart && frame.FrameType is RenderTreeFrameType.ComponentRenderMode) + { + return frame.ComponentRenderMode; + } + } + } + + return null; + } } #endif diff --git a/tests/bunit.core.tests/Rendering/RenderModeTests.cs b/tests/bunit.core.tests/Rendering/RenderModeTests.cs deleted file mode 100644 index 352da9dec..000000000 --- a/tests/bunit.core.tests/Rendering/RenderModeTests.cs +++ /dev/null @@ -1,73 +0,0 @@ -#if NET9_0_OR_GREATER -using Bunit.TestAssets.RenderModes; - -namespace Bunit.Rendering; - -public class RenderModeTests : TestContext -{ - [Fact(DisplayName = "TestRenderer provides RendererInfo")] - public void Test001() - { - Renderer.SetRendererInfo(new RendererInfo("Server", true)); - var cut = RenderComponent(); - - cut.MarkupMatches(""" -

Is interactive: True

-

Rendermode: Server

- """); - } - - [Fact(DisplayName = "Renderer throws exception if RendererInfo is not specified")] - public void Test002() - { - Action act = () => RenderComponent(); - - act.ShouldThrow(); - } - - [Fact(DisplayName = "Renderer should set the RenderModeAttribute on the component")] - public void Test003() - { - var cut = RenderComponent(); - - cut.MarkupMatches("
Assigned render mode: InteractiveServerRenderMode
"); - } - - [Fact(DisplayName = "The AssignedRenderMode is based on the RenderModeAttribute in the component hierarchy where parent component has no RenderMode")] - public void Test004() - { - var cut = RenderComponent( - c => c.AddChildContent()); - - cut.MarkupMatches(""" -
Parent assigned render mode:
-
Assigned render mode: InteractiveWebAssemblyRenderMode
- """); - } - - [Fact(DisplayName = "Parent and child render mode is specified")] - public void Test005() - { - var cut = RenderComponent( - c => c.AddChildContent()); - - cut.MarkupMatches(""" -
Parent assigned render mode: InteractiveWebAssemblyRenderMode
-
Assigned render mode: InteractiveServerRenderMode
- """); - } - - [Fact(DisplayName = "Parent and child render mode is not specified")] - public void Test006() - { - var cut = RenderComponent( - c => c.AddChildContent()); - - cut.MarkupMatches(""" -
Parent assigned render mode:
-
Assigned render mode:
- """); - - } -} -#endif \ No newline at end of file diff --git a/tests/bunit.core.tests/Rendering/RenderModeTests.razor b/tests/bunit.core.tests/Rendering/RenderModeTests.razor new file mode 100644 index 000000000..d9a0fb514 --- /dev/null +++ b/tests/bunit.core.tests/Rendering/RenderModeTests.razor @@ -0,0 +1,142 @@ +@using Bunit.TestAssets.RenderModes; +@inherits TestContext +@code { +#if NET9_0_OR_GREATER + [Fact(DisplayName = "TestRenderer provides RendererInfo")] + public void Test001() + { + Renderer.SetRendererInfo(new RendererInfo("Server", true)); + var cut = RenderComponent(); + + cut.MarkupMatches( + @ +

Is interactive: True

+

Rendermode: Server

+
); + } + + [Fact(DisplayName = "Renderer throws exception if RendererInfo is not specified")] + public void Test002() + { + Action act = () => RenderComponent(); + + act.ShouldThrow(); + } + + [Fact(DisplayName = "Renderer should set the RenderModeAttribute on the component")] + public void Test003() + { + var cut = RenderComponent(); + + cut.MarkupMatches(@
Assigned render mode: InteractiveServerRenderMode
); + } + + [Fact(DisplayName = "The AssignedRenderMode is based on the RenderModeAttribute in the component hierarchy where parent component has no RenderMode")] + public void Test004() + { + var cut = Render( + @ + + ); + + cut.MarkupMatches( + @ +
Parent assigned render mode:
+
Assigned render mode: InteractiveWebAssemblyRenderMode
+
); + } + + [Fact(DisplayName = "Parent and child render mode is specified")] + public void Test005() + { + var cut = Render( + @ + + ); + + cut.MarkupMatches( + @ +
Parent assigned render mode: InteractiveServerRenderMode
+
Assigned render mode: InteractiveServerRenderMode
+
); + } + + [Fact(DisplayName = "Parent and child render mode is not specified")] + public void Test006() + { + var cut = Render( + @ + + ); + + cut.MarkupMatches( + @ +
Parent assigned render mode:
+
Assigned render mode:
+
); + } + + [Fact(DisplayName = "Rendermode specified on child")] + public void Test007() + { + var cut = Render( + @ + + ); + + cut.MarkupMatches(@

Assigned Render Mode: InteractiveServerRenderMode

); + } + + [Fact(DisplayName = "Assigned Render Mode is inherited all the way down the component hierarchy")] + public void Test008() + { + var cut = Render( + @ + + + + ); + + cut.MarkupMatches(@

Assigned Render Mode: InteractiveServerRenderMode

); + } + + [Fact(DisplayName = "Having a component with section outlet and RenderMode is specifying for child component")] + public void Test009() + { + // See: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/sections?view=aspnetcore-8.0#section-interaction-with-other-blazor-features + var cut = Render(@); + + cut.MarkupMatches(@

Assigned Render Mode: InteractiveWebAssemblyRenderMode

); + } + + [Fact(DisplayName = "Assigned Render Mode on siblings")] + public void Test010() + { + var cut = Render( + @ + + + ); + + cut.MarkupMatches( + @ +

Assigned Render Mode: InteractiveServerRenderMode

+

Assigned Render Mode: InteractiveWebAssemblyRenderMode

+
); + } + + + [Fact(DisplayName = "Different assigned RenderMode between child and parent throws")] + public void Test020() + { + var act = () => Render( + @ + + + + ); + + act.ShouldThrow(); // todo: figure out good exception to use + } +#endif +} diff --git a/tests/bunit.testassets/RenderModes/ComponentThatPrintsAssignedRenderMode.razor b/tests/bunit.testassets/RenderModes/ComponentThatPrintsAssignedRenderMode.razor new file mode 100644 index 000000000..effe0ff2c --- /dev/null +++ b/tests/bunit.testassets/RenderModes/ComponentThatPrintsAssignedRenderMode.razor @@ -0,0 +1,9 @@ +@{ +#if NET9_0_OR_GREATER +} + +

Assigned Render Mode: @AssignedRenderMode?.GetType().Name

+ +@{ +#endif +} diff --git a/tests/bunit.testassets/RenderModes/ComponentWithChildContent.razor b/tests/bunit.testassets/RenderModes/ComponentWithChildContent.razor new file mode 100644 index 000000000..c8b0cd4e1 --- /dev/null +++ b/tests/bunit.testassets/RenderModes/ComponentWithChildContent.razor @@ -0,0 +1,6 @@ +@ChildContent +@code { + + [Parameter] public RenderFragment ChildContent { get; set; } = default!; + +} \ No newline at end of file diff --git a/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor b/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor index 3ce1d35a0..dd008df6c 100644 --- a/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor +++ b/tests/bunit.testassets/RenderModes/ComponentWithServerRenderMode.razor @@ -12,4 +12,4 @@ @{ #endif -} \ No newline at end of file +} diff --git a/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor b/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor new file mode 100644 index 000000000..7e860e07d --- /dev/null +++ b/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor @@ -0,0 +1,12 @@ +@{ +#if NET9_0_OR_GREATER +} + + + + + + +@{ +#endif +} From 1e032b941c6d3a950869c4424de6515c2fca6075 Mon Sep 17 00:00:00 2001 From: Egil Hansen Date: Fri, 15 Nov 2024 16:29:59 +0000 Subject: [PATCH 6/9] fix: support passing assigned render mode via parameter builder --- Directory.Build.props | 1 + .../ComponentParameterCollection.cs | 11 +++++ .../ComponentParameterCollectionBuilder.cs | 29 ++++++++++---- .../Rendering/RenderModeTests.razor | 40 +++++++++++++++++-- .../RenderModes/SectionOutletComponent.cs | 30 ++++++++++++++ .../RenderModes/SectionOutletComponent.razor | 12 ------ .../bunit.testassets/bunit.testassets.csproj | 1 + 7 files changed, 101 insertions(+), 23 deletions(-) create mode 100644 tests/bunit.testassets/RenderModes/SectionOutletComponent.cs delete mode 100644 tests/bunit.testassets/RenderModes/SectionOutletComponent.razor diff --git a/Directory.Build.props b/Directory.Build.props index a3c2a053a..b2194a03c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -16,6 +16,7 @@ enable CA1014,NU5104,NETSDK1138,SYSLIB0051 false + true full diff --git a/src/bunit.core/ComponentParameterCollection.cs b/src/bunit.core/ComponentParameterCollection.cs index 7b248b096..9f179bc94 100644 --- a/src/bunit.core/ComponentParameterCollection.cs +++ b/src/bunit.core/ComponentParameterCollection.cs @@ -19,6 +19,14 @@ public class ComponentParameterCollection : ICollection, IRe /// public bool IsReadOnly { get; } +#if NET9_0_OR_GREATER + /// + /// Gets or sets the that will be specified in + /// the render tree for component the parameters are being passed to. + /// + public IComponentRenderMode? RenderMode { get; set; } +#endif + /// /// Adds a to the collection. /// @@ -104,6 +112,9 @@ void AddComponent(RenderTreeBuilder builder) { builder.OpenComponent(0); AddAttributes(builder); +#if NET9_0_OR_GREATER + builder.AddComponentRenderMode(RenderMode); +#endif builder.CloseComponent(); } diff --git a/src/bunit.core/ComponentParameterCollectionBuilder.cs b/src/bunit.core/ComponentParameterCollectionBuilder.cs index f4c1fa04e..492b035a5 100644 --- a/src/bunit.core/ComponentParameterCollectionBuilder.cs +++ b/src/bunit.core/ComponentParameterCollectionBuilder.cs @@ -78,7 +78,7 @@ public ComponentParameterCollectionBuilder Add(Expr /// A lambda function that selects the parameter. /// The markup string to pass to the . /// This . - public ComponentParameterCollectionBuilder Add(Expression> parameterSelector, [StringSyntax("Html")]string markup) + public ComponentParameterCollectionBuilder Add(Expression> parameterSelector, [StringSyntax("Html")] string markup) => Add(parameterSelector, markup.ToMarkupRenderFragment()); /// @@ -266,7 +266,7 @@ public ComponentParameterCollectionBuilder AddChildContent(RenderFra /// /// The markup string to pass the ChildContent parameter wrapped in a . /// This . - public ComponentParameterCollectionBuilder AddChildContent([StringSyntax("Html")]string markup) + public ComponentParameterCollectionBuilder AddChildContent([StringSyntax("Html")] string markup) => AddChildContent(markup.ToMarkupRenderFragment()); /// @@ -344,11 +344,11 @@ public ComponentParameterCollectionBuilder Bind( Action changedAction, Expression>? valueExpression = null) { - #if !NET8_0_OR_GREATER +#if !NET8_0_OR_GREATER var (parameterName, _, isCascading) = GetParameterInfo(parameterSelector); - #else +#else var (parameterName, _, isCascading) = GetParameterInfo(parameterSelector, initialValue); - #endif +#endif if (isCascading) throw new ArgumentException("Using Bind with a cascading parameter is not allowed.", parameterName); @@ -397,6 +397,19 @@ static string TrimEnd(string source, string value) : source; } +#if NET9_0_OR_GREATER + /// + /// Sets (or unsets) the for the component and child components. + /// + /// The render mode to assign to the component, e.g. RenderMode.InteractiveServer, or , to not assign a specific render mode. + /// This . + public ComponentParameterCollectionBuilder SetAssignedRenderMode(IComponentRenderMode? renderMode) + { + parameters.RenderMode = renderMode; + return this; + } +#endif + /// /// Try to add a for a parameter with the , if /// has a property with that name, AND that property has a @@ -454,14 +467,14 @@ Expression> parameterSelector : propInfoCandidate; var paramAttr = propertyInfo?.GetCustomAttribute(inherit: true); - #if !NET8_0_OR_GREATER +#if !NET8_0_OR_GREATER var cascadingParamAttr = propertyInfo?.GetCustomAttribute(inherit: true); if (propertyInfo is null || (paramAttr is null && cascadingParamAttr is null)) throw new ArgumentException($"The parameter selector '{parameterSelector}' does not resolve to a public property on the component '{typeof(TComponent)}' with a [Parameter] or [CascadingParameter] attribute.", nameof(parameterSelector)); return (propertyInfo.Name, CascadingValueName: cascadingParamAttr?.Name, IsCascading: cascadingParamAttr is not null); - #else +#else var cascadingParamAttrBase = propertyInfo?.GetCustomAttribute(inherit: true); if (propertyInfo is null || (paramAttr is null && cascadingParamAttrBase is null)) @@ -494,7 +507,7 @@ static ArgumentException CreateErrorMessageForSupplyFromQuery( NavigationManager.NavigateTo(uri); """); } - #endif +#endif } private static bool HasChildContentParameter() diff --git a/tests/bunit.core.tests/Rendering/RenderModeTests.razor b/tests/bunit.core.tests/Rendering/RenderModeTests.razor index d9a0fb514..e389650f3 100644 --- a/tests/bunit.core.tests/Rendering/RenderModeTests.razor +++ b/tests/bunit.core.tests/Rendering/RenderModeTests.razor @@ -1,7 +1,9 @@ +@code{ + #if NET9_0_OR_GREATER +} @using Bunit.TestAssets.RenderModes; @inherits TestContext @code { -#if NET9_0_OR_GREATER [Fact(DisplayName = "TestRenderer provides RendererInfo")] public void Test001() { @@ -104,7 +106,7 @@ public void Test009() { // See: https://learn.microsoft.com/en-us/aspnet/core/blazor/components/sections?view=aspnetcore-8.0#section-interaction-with-other-blazor-features - var cut = Render(@); + var cut = Render(@); cut.MarkupMatches(@

Assigned Render Mode: InteractiveWebAssemblyRenderMode

); } @@ -125,6 +127,36 @@ ); } + [Fact(DisplayName = "SetAssignedRenderMode on root component")] + public void Test011() + { + var cut = RenderComponent(ps => ps.SetAssignedRenderMode(RenderMode.InteractiveServer)); + cut.MarkupMatches(@

Assigned Render Mode: InteractiveServerRenderMode

); + } + + [Fact(DisplayName = "SetAssignedRenderMode on parent component cascades to children")] + public void Test012() + { + var cut = RenderComponent(ps => ps + .SetAssignedRenderMode(RenderMode.InteractiveWebAssembly) + .AddChildContent()); + + cut.MarkupMatches(@

Assigned Render Mode: InteractiveWebAssemblyRenderMode

); + } + + [Fact(DisplayName = "SetAssignedRenderMode child components")] + public void Test013() + { + var cut = RenderComponent(ps => ps + .AddChildContent(pps => pps.SetAssignedRenderMode(RenderMode.InteractiveServer)) + .AddChildContent(pps => pps.SetAssignedRenderMode(RenderMode.InteractiveWebAssembly))); + + cut.MarkupMatches( + @ +

Assigned Render Mode: InteractiveServerRenderMode

+

Assigned Render Mode: InteractiveWebAssemblyRenderMode

+
); + } [Fact(DisplayName = "Different assigned RenderMode between child and parent throws")] public void Test020() @@ -138,5 +170,7 @@ act.ShouldThrow(); // todo: figure out good exception to use } -#endif +} +@code{ + #endif } diff --git a/tests/bunit.testassets/RenderModes/SectionOutletComponent.cs b/tests/bunit.testassets/RenderModes/SectionOutletComponent.cs new file mode 100644 index 000000000..70dd7d9a1 --- /dev/null +++ b/tests/bunit.testassets/RenderModes/SectionOutletComponent.cs @@ -0,0 +1,30 @@ +using Microsoft.AspNetCore.Components.Web; + +#if NET8_0_OR_GREATER +using Microsoft.AspNetCore.Components.Sections; +#endif + +namespace Bunit.TestAssets.RenderModes; + +public class SectionOutletComponent : ComponentBase +{ +#if NET8_0_OR_GREATER + private static readonly Guid SectionId = Guid.NewGuid(); +#endif + + [Parameter] public RenderFragment ChildContent { get; set; } + + protected override void BuildRenderTree(RenderTreeBuilder builder) + { +#if NET8_0_OR_GREATER + builder.OpenComponent(0); + builder.AddComponentParameter(1, nameof(SectionOutlet.SectionId), SectionId); + builder.AddComponentRenderMode(RenderMode.InteractiveWebAssembly); + builder.CloseComponent(); + builder.OpenComponent(10); + builder.AddComponentParameter(11, nameof(SectionContent.SectionId), SectionId); + builder.AddAttribute(12, nameof(SectionContent.ChildContent), ChildContent); + builder.CloseComponent(); +#endif + } +} diff --git a/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor b/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor deleted file mode 100644 index 7e860e07d..000000000 --- a/tests/bunit.testassets/RenderModes/SectionOutletComponent.razor +++ /dev/null @@ -1,12 +0,0 @@ -@{ -#if NET9_0_OR_GREATER -} - - - - - - -@{ -#endif -} diff --git a/tests/bunit.testassets/bunit.testassets.csproj b/tests/bunit.testassets/bunit.testassets.csproj index 424468974..183551378 100644 --- a/tests/bunit.testassets/bunit.testassets.csproj +++ b/tests/bunit.testassets/bunit.testassets.csproj @@ -20,6 +20,7 @@ + From a4c5161cfa7277a1509ae838baf0bfec4f86aa3a Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Wed, 27 Nov 2024 15:59:35 +0100 Subject: [PATCH 7/9] docs: Added docs and exposes via TestContext --- .vscode/tasks.json | 4 +- docs/site/docs/interaction/index.md | 1 + docs/site/docs/interaction/render-modes.md | 157 ++++++++++++++++++ docs/site/docs/toc.md | 1 + .../Rendering/MissingRendererInfoException.cs | 13 +- src/bunit.core/TestContextBase.cs | 10 ++ src/bunit.web/TestContextWrapper.cs | 7 + .../Rendering/RenderModeTests.razor | 2 +- 8 files changed, 187 insertions(+), 8 deletions(-) create mode 100644 docs/site/docs/interaction/render-modes.md diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9aebda5c8..458ec69a3 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -6,12 +6,12 @@ { "label": "Serve Docs (Without Build)", "type": "shell", - "command": "docfx metadata docs/site/docfx.json && docfx docs/site/docfx.json --serve" + "command": "dotnet docfx metadata docs/site/docfx.json && dotnet docfx docs/site/docfx.json --serve" }, { "label": "Serve Docs (With Build for API Documentation)", "type": "shell", - "command": "dotnet build -c Release && docfx metadata docs/site/docfx.json && docfx docs/site/docfx.json --serve" + "command": "dotnet build -c Release && dotnet docfx metadata docs/site/docfx.json && docfx docs/site/docfx.json --serve" }, { "label": "Run all tests (Release Mode)", diff --git a/docs/site/docs/interaction/index.md b/docs/site/docs/interaction/index.md index 96e06fdde..9967c90ea 100644 --- a/docs/site/docs/interaction/index.md +++ b/docs/site/docs/interaction/index.md @@ -11,3 +11,4 @@ This section covers the various ways to interact with a component under test, e. - **:** This covers how to manually trigger a render cycle for a component under test. - **:** This covers how to await one or more asynchronous changes to the state of a component under test before continuing the test. - **:** This covers how to dispose components and their children. +- **:** This covers the different render modes and their interaction with bUnit. diff --git a/docs/site/docs/interaction/render-modes.md b/docs/site/docs/interaction/render-modes.md new file mode 100644 index 000000000..fc40eee6d --- /dev/null +++ b/docs/site/docs/interaction/render-modes.md @@ -0,0 +1,157 @@ +--- +uid: render-modes +title: Render modes and RendererInfo +--- + +# Support for render modes and `RendererInfo` +This article explains how to emulate different render modes and `RendererInfo` in bUnit tests. + +Render modes in Blazor Web Apps determine the hosting model and interactivity of components. A render mode can be applied to a component using the `@rendermode` directive. The [`RendererInfo`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.rendererinfo?view=aspnetcore-9.0) allows the application to determine the interactivity and location of the component. For more details, see the [Blazor render modes](https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-9.0) documentation. + +## Setting the render mode for a component under test +Setting the render mode can be done via the method when writing in a C# file. In a razor file use the `@rendermode` directive. Both take an [`IComponentRenderMode`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.icomponentrendermode?view=aspnetcore-9.0) object as a parameter. Normally this is one of the following types: + * [`InteractiveAutoRenderMode`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.web.interactiveautorendermode?view=aspnetcore-9.0) + * [`InteractiveServerRendeMode`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.web.interactiveserverrendermode?view=aspnetcore-9.0) + * [`InteractiveWebAssemblyRenderMode`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.web.interactivewebassemblyrendermode?view=aspnetcore-9.0) + +For ease of use the [`RenderMode`](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.web.rendermode?view=aspnetcore-9.0) class defines all three of them. + +For example `MovieComponent.razor`: +```razor +@if (AssignedRenderMode is null) +{ + // The render mode is Static Server +
+ + +
+} +else +{ + // The render mode is Interactive Server, WebAssembly, or Auto + + +} +``` + +The following example shows how to test the above component to check both render modes: + +# [C# test code](#tab/csharp) + +```csharp +[Fact] +public void InteractiveServer() +{ + // Act + var cut = RenderComponent(ps => ps + .SetAssignedRenderMode(RenderMode.InteractiveServer)); + + // Assert + cut.MarkupMatches(""" + + + """); +} + +[Fact] +public void StaticRendering() +{ + // Act + var cut = RenderComponent(); + // This is the same behavior as: + // var cut = RenderComponent(ps => ps + // .SetAssignedRenderMode(null)); + + // Assert + cut.MarkupMatches(""" +
+ + +
+ """); +} +``` + +# [Razor test code](#tab/razor) + +```razor +@inherits TestContext +@code { + [Fact] + public void InteractiveServer() + { + // Act + var cut = Render(@); + + // Assert + cut.MarkupMatches(@ + + + ); + } + + [Fact] + public void StaticRendering() + { + // Act + var cut = Render(@); + + // Assert + cut.MarkupMatches(@
+ + +
); + } +} +``` + +*** + +## Setting the `RendererInfo` during testing +To control the `ComponentBase.RendererInfo` property during testing, use the method on the `TestContext` class. The `SetRendererInfo` method takes an nullable `RendererInfo` object as a parameter. Passing `null` will set the `ComponentBase.RendererInfo` to `null`. + +A component (`AssistentComponent.razor`) might check if interactivity is given to enable a button: + +```razor +@if (RendererInfo.IsInteractive) +{ +

Hey I am your assistant

+} +else +{ +

Loading...

+} +``` + +In the test, you can set the `RendererInfo` to enable or disable the button: + +```csharp +[Fact] +public void SimulatingPreRenderingOnBlazorServer() +{ + // Arrange + SetRendererInfo(new RendererInfo(rendererName: "Static", isInteractive: false)); + + // Act + var cut = RenderComponent(); + + // Assert + cut.MarkupMatches("

Loading...

"); +} + +[Fact] +public void SimulatingInteractiveServerRendering() +{ + // Arrange + SetRendererInfo(new RendererInfo(rendererMode: "Server", isInteractive: true)); + + // Act + var cut = RenderComponent(); + + // Assert + cut.MarkupMatches("

Hey I am your assistant

"); +} +``` + +> [!NOTE] +> If a component under test uses the `ComponentBase.RendererInfo` property and the `SetRendererInfo` on `TestContext` hasn't been passed in a `RendererInfo` object, the renderer will throw an exception. \ No newline at end of file diff --git a/docs/site/docs/toc.md b/docs/site/docs/toc.md index 327afde06..8d937b05c 100644 --- a/docs/site/docs/toc.md +++ b/docs/site/docs/toc.md @@ -14,6 +14,7 @@ ## [Trigger renders](xref:trigger-renders) ## [Awaiting an async state change](xref:awaiting-async-state) ## [Disposing components](xref:dispose-components) +## [Render modes and RendererInfo](xref:render-modes) # [Verifying output](xref:verification) ## [Verify markup](xref:verify-markup) diff --git a/src/bunit.core/Rendering/MissingRendererInfoException.cs b/src/bunit.core/Rendering/MissingRendererInfoException.cs index 147a254fe..a763a0d98 100644 --- a/src/bunit.core/Rendering/MissingRendererInfoException.cs +++ b/src/bunit.core/Rendering/MissingRendererInfoException.cs @@ -18,16 +18,19 @@ public MissingRendererInfoException() public class SomeTestClass : TestContext { [Fact] - public void SomeTestCase() - { - Renderer.SetRendererInfo(new RendererInfo("Server", true)); - ... + public void SomeTestCase() + { + SetRendererInfo(new RendererInfo("Server", true)); + ... } } - + The four built in render names are 'Static', 'Server', 'WebAssembly', and 'WebView'. + + Go to https://bunit.dev/docs/interaction/render-modes for more information. """) { + HelpLink = "https://bunit.dev/docs/interaction/render-modes"; } } #endif diff --git a/src/bunit.core/TestContextBase.cs b/src/bunit.core/TestContextBase.cs index 9c2fa1e8a..d9e3edce8 100644 --- a/src/bunit.core/TestContextBase.cs +++ b/src/bunit.core/TestContextBase.cs @@ -118,4 +118,14 @@ public void DisposeComponents() { Renderer.DisposeComponents(); } + +#if NET9_0_OR_GREATER + /// + /// Sets the for the renderer. + /// + public void SetRendererInfo(RendererInfo? rendererInfo) + { + Renderer.SetRendererInfo(rendererInfo); + } +#endif } diff --git a/src/bunit.web/TestContextWrapper.cs b/src/bunit.web/TestContextWrapper.cs index a6a9c57c0..1ddb194d5 100644 --- a/src/bunit.web/TestContextWrapper.cs +++ b/src/bunit.web/TestContextWrapper.cs @@ -83,6 +83,13 @@ public virtual IRenderedFragment Render(RenderFragment renderFragment) ///
public virtual void DisposeComponents() => TestContext?.DisposeComponents(); +#if NET9_0_OR_GREATER + /// + /// Sets the for the renderer. + /// + public virtual void SetRendererInfo(RendererInfo? rendererInfo) => TestContext?.SetRendererInfo(rendererInfo); +#endif + /// /// Dummy method required to allow Blazor's compiler to generate /// C# from .razor files. diff --git a/tests/bunit.core.tests/Rendering/RenderModeTests.razor b/tests/bunit.core.tests/Rendering/RenderModeTests.razor index e389650f3..0bded05f6 100644 --- a/tests/bunit.core.tests/Rendering/RenderModeTests.razor +++ b/tests/bunit.core.tests/Rendering/RenderModeTests.razor @@ -7,7 +7,7 @@ [Fact(DisplayName = "TestRenderer provides RendererInfo")] public void Test001() { - Renderer.SetRendererInfo(new RendererInfo("Server", true)); + SetRendererInfo(new RendererInfo("Server", true)); var cut = RenderComponent(); cut.MarkupMatches( From 46e416c8d52dc49778baa06a9278cb4c832fea1e Mon Sep 17 00:00:00 2001 From: Steven Giesel Date: Fri, 13 Dec 2024 16:50:33 +0100 Subject: [PATCH 8/9] chore: Update packages --- .config/dotnet-tools.json | 2 +- Directory.Packages.props | 46 +++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/.config/dotnet-tools.json b/.config/dotnet-tools.json index 10bd8b7a3..294e26e0b 100644 --- a/.config/dotnet-tools.json +++ b/.config/dotnet-tools.json @@ -10,7 +10,7 @@ "rollForward": false }, "docfx": { - "version": "2.77.0", + "version": "2.78.2", "commands": [ "docfx" ], diff --git a/Directory.Packages.props b/Directory.Packages.props index c25fef9bc..48d1d7ddb 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,7 +8,7 @@ - + @@ -28,7 +28,7 @@ - + @@ -58,16 +58,16 @@ - + - - - - - - - - + + + + + + + + @@ -86,14 +86,14 @@ - + - - + + - - - + + + @@ -103,7 +103,7 @@ - + @@ -122,7 +122,7 @@ - + @@ -140,10 +140,10 @@ - - - - + + + + From 5a2c0f47a14323846967a9608f5f9eb22c78fe17 Mon Sep 17 00:00:00 2001 From: bUnit bot Date: Fri, 13 Dec 2024 16:03:22 +0000 Subject: [PATCH 9/9] Set version to '1.37' --- version.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.json b/version.json index 4b460b45b..4c937cfb9 100644 --- a/version.json +++ b/version.json @@ -1,6 +1,6 @@ { "$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/main/src/NerdBank.GitVersioning/version.schema.json", - "version": "1.37-preview", + "version": "1.37", "assemblyVersion": { "precision": "revision" },