33using System . Linq ;
44using System . Runtime . ExceptionServices ;
55using System . Text ;
6+ using System . Threading ;
67using System . Threading . Tasks ;
78using Bunit . RazorTesting ;
89using Microsoft . AspNetCore . Components ;
10+ using Microsoft . AspNetCore . Components . Rendering ;
911using Microsoft . AspNetCore . Components . RenderTree ;
1012using Microsoft . Extensions . DependencyInjection ;
1113using Microsoft . Extensions . Logging ;
@@ -19,6 +21,7 @@ namespace Bunit.Rendering
1921 public class TestComponentRenderer : Renderer
2022 {
2123 private static readonly ServiceProvider ServiceProvider = new ServiceCollection ( ) . BuildServiceProvider ( ) ;
24+ private static readonly Task CanceledRenderTask = Task . FromCanceled ( new CancellationToken ( canceled : true ) ) ;
2225 private Exception ? _unhandledException ;
2326
2427 /// <inheritdoc/>
@@ -40,67 +43,50 @@ public TestComponentRenderer(IServiceProvider serviceProvider, ILoggerFactory lo
4043 /// </summary>
4144 /// <param name="componentType">Razor-based test to render.</param>
4245 /// <returns>A list of <see cref="FragmentBase"/> test definitions found in the test file.</returns>
43- public async Task < IReadOnlyList < RazorTestBase > > GetRazorTestsFromComponent ( Type componentType )
46+ public IReadOnlyList < RazorTestBase > GetRazorTestsFromComponent ( Type componentType )
4447 {
45- var componentId = await Dispatcher . InvokeAsync ( ( ) => RenderComponent ( componentType ) ) . ConfigureAwait ( false ) ;
46- AssertNoUnhandledExceptions ( ) ;
48+ var componentId = RenderComponent ( componentType ) ;
4749 return GetRazorTests < RazorTestBase > ( componentId ) ;
4850 }
4951
50- /// <summary>
51- /// Renders the provided <paramref name="renderFragment"/>.
52- /// </summary>
53- /// <typeparam name="TComponent">The type of components to find in the render tree after rendering.</typeparam>
54- /// <param name="renderFragment">The <see cref="RenderFragment"/> to render.</param>
55- /// <returns>A list of <typeparamref name="TComponent"/> found in the <paramref name="renderFragment"/>'s render tree.</returns>
56- public async Task < IReadOnlyList < TComponent > > RenderAndGetTestComponents < TComponent > ( RenderFragment renderFragment )
52+ private int RenderComponent ( Type componentType )
5753 {
58- var componentId = await RenderFragmentInsideWrapper ( renderFragment ) ;
59- return GetRazorTests < TComponent > ( componentId ) ;
60- }
54+ int componentId = - 1 ;
6155
62- private async Task < int > RenderComponent ( Type componentType )
63- {
64- var component = InstantiateComponent ( componentType ) ;
65- AssertNoUnhandledExceptions ( ) ;
66- var componentId = AssignRootComponentId ( component ) ;
67- AssertNoUnhandledExceptions ( ) ;
56+ Dispatcher . InvokeAsync ( ( ) =>
57+ {
58+ var component = InstantiateComponent ( componentType ) ;
59+ componentId = AssignRootComponentId ( component ) ;
60+ return RenderRootComponentAsync ( componentId ) ;
61+ } ) . Wait ( ) ;
6862
69- await RenderRootComponentAsync ( componentId ) . ConfigureAwait ( false ) ;
7063 AssertNoUnhandledExceptions ( ) ;
7164
7265 return componentId ;
7366 }
7467
75- private async Task < int > RenderFragmentInsideWrapper ( RenderFragment renderFragment )
68+ private IReadOnlyList < TComponent > GetRazorTests < TComponent > ( int fromComponentId )
7669 {
77- var wrapper = new WrapperComponent ( ) ;
78-
79- var wrapperId = AssignRootComponentId ( wrapper ) ;
80- AssertNoUnhandledExceptions ( ) ;
81-
82- await Dispatcher . InvokeAsync ( ( ) => wrapper . Render ( renderFragment ) ) . ConfigureAwait ( false ) ;
83- AssertNoUnhandledExceptions ( ) ;
70+ var ownFrames = GetCurrentRenderTreeFrames ( fromComponentId ) ;
8471
85- return wrapperId ;
86- }
72+ if ( ownFrames . Count == 0 )
73+ return Array . Empty < TComponent > ( ) ;
8774
88- private IReadOnlyList < TComponent > GetRazorTests < TComponent > ( int fromComponentId )
89- {
9075 var result = new List < TComponent > ( ) ;
91- var ownFrames = GetCurrentRenderTreeFrames ( fromComponentId ) ;
76+
9277 for ( var i = 0 ; i < ownFrames . Count ; i ++ )
9378 {
9479 ref var frame = ref ownFrames . Array [ i ] ;
9580 if ( frame . FrameType == RenderTreeFrameType . Component )
9681 if ( frame . Component is TComponent component )
9782 result . Add ( component ) ;
9883 }
84+
9985 return result ;
10086 }
10187
10288 /// <inheritdoc/>
103- protected override Task UpdateDisplayAsync ( in RenderBatch renderBatch ) => Task . CompletedTask ;
89+ protected override Task UpdateDisplayAsync ( in RenderBatch renderBatch ) => CanceledRenderTask ;
10490
10591 /// <inheritdoc/>
10692 protected override void HandleException ( Exception exception ) => _unhandledException = exception ;
@@ -113,19 +99,5 @@ private void AssertNoUnhandledExceptions()
11399 ExceptionDispatchInfo . Capture ( unhandled ) . Throw ( ) ;
114100 }
115101 }
116-
117- private class WrapperComponent : IComponent
118- {
119- private RenderHandle _renderHandle ;
120-
121- public void Attach ( RenderHandle renderHandle ) => _renderHandle = renderHandle ;
122-
123- public Task SetParametersAsync ( ParameterView parameters ) => throw new InvalidOperationException ( $ "WrapperComponent shouldn't receive any parameters") ;
124-
125- public void Render ( RenderFragment renderFragment )
126- {
127- _renderHandle . Render ( renderFragment ) ;
128- }
129- }
130102 }
131103}
0 commit comments