-
Notifications
You must be signed in to change notification settings - Fork 0
Code Review Bench PR #64643 - Add test coverage for prerendering closed generic components #5
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
base: base_pr_64643_20260125_6926
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| @typeparam TValue | ||
|
|
||
| <p>Generic value: @(Value?.ToString() ?? "(null)")</p> | ||
| @code { | ||
| [Parameter] public TValue Value { get; set; } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,15 +1,16 @@ | ||||||
| // Licensed to the .NET Foundation under one or more agreements. | ||||||
| // The .NET Foundation licenses this file to you under the MIT license. | ||||||
|
|
||||||
| using System.Globalization; | ||||||
| using System.Text.Json; | ||||||
| using Microsoft.AspNetCore.Components.Endpoints; | ||||||
| using Microsoft.AspNetCore.DataProtection; | ||||||
| using Microsoft.Extensions.Logging.Abstractions; | ||||||
|
|
||||||
| namespace Microsoft.AspNetCore.Components.Server.Circuits; | ||||||
|
|
||||||
| public class ServerComponentDeserializerTest | ||||||
| namespace Microsoft.AspNetCore.Components.Server.Circuits | ||||||
| { | ||||||
| public class ServerComponentDeserializerTest | ||||||
| { | ||||||
| private readonly IDataProtectionProvider _ephemeralDataProtectionProvider; | ||||||
| private readonly ITimeLimitedDataProtector _protector; | ||||||
| private ServerComponentInvocationSequence _invocationSequence = new(); | ||||||
|
|
@@ -75,6 +76,74 @@ public void CanParseSingleMarkerWithNullParameters() | |||||
| Assert.Null(parameters["Parameter"]); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void CanParseSingleMarkerForClosedGenericComponent() | ||||||
| { | ||||||
| // Arrange | ||||||
| var markers = SerializeMarkers(CreateMarkers(typeof(GenericTestComponent<int>))); | ||||||
| var serverComponentDeserializer = CreateServerComponentDeserializer(); | ||||||
|
|
||||||
| // Act & assert | ||||||
| Assert.True(serverComponentDeserializer.TryDeserializeComponentDescriptorCollection(markers, out var descriptors)); | ||||||
| var deserializedDescriptor = Assert.Single(descriptors); | ||||||
| Assert.Equal(typeof(GenericTestComponent<int>).FullName, deserializedDescriptor.ComponentType.FullName); | ||||||
| Assert.Equal(0, deserializedDescriptor.Sequence); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void CanParseSingleMarkerForClosedGenericComponentWithStringTypeParameter() | ||||||
| { | ||||||
| // Arrange | ||||||
| var markers = SerializeMarkers(CreateMarkers(typeof(GenericTestComponent<string>))); | ||||||
| var serverComponentDeserializer = CreateServerComponentDeserializer(); | ||||||
|
|
||||||
| // Act & assert | ||||||
| Assert.True(serverComponentDeserializer.TryDeserializeComponentDescriptorCollection(markers, out var descriptors)); | ||||||
| var deserializedDescriptor = Assert.Single(descriptors); | ||||||
| Assert.Equal(typeof(GenericTestComponent<string>).FullName, deserializedDescriptor.ComponentType.FullName); | ||||||
| Assert.Equal(0, deserializedDescriptor.Sequence); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void CanParseSingleMarkerForClosedGenericComponentWithParameters() | ||||||
| { | ||||||
| // Arrange | ||||||
| var markers = SerializeMarkers(CreateMarkers( | ||||||
| (typeof(GenericTestComponent<int>), new Dictionary<string, object> { ["Value"] = 42 }))); | ||||||
| var serverComponentDeserializer = CreateServerComponentDeserializer(); | ||||||
|
|
||||||
| // Act & assert | ||||||
| Assert.True(serverComponentDeserializer.TryDeserializeComponentDescriptorCollection(markers, out var descriptors)); | ||||||
| var deserializedDescriptor = Assert.Single(descriptors); | ||||||
| Assert.Equal(typeof(GenericTestComponent<int>).FullName, deserializedDescriptor.ComponentType.FullName); | ||||||
| Assert.Equal(0, deserializedDescriptor.Sequence); | ||||||
|
|
||||||
| var parameters = deserializedDescriptor.Parameters.ToDictionary(); | ||||||
| Assert.Single(parameters); | ||||||
| Assert.Contains("Value", parameters.Keys); | ||||||
| Assert.Equal(42, Convert.ToInt64(parameters["Value"]!, CultureInfo.InvariantCulture)); | ||||||
| } | ||||||
|
|
||||||
| [Fact] | ||||||
| public void CanParseMultipleMarkersForClosedGenericComponents() | ||||||
| { | ||||||
| // Arrange | ||||||
| var markers = SerializeMarkers(CreateMarkers(typeof(GenericTestComponent<int>), typeof(GenericTestComponent<string>))); | ||||||
| var serverComponentDeserializer = CreateServerComponentDeserializer(); | ||||||
|
|
||||||
| // Act & assert | ||||||
| Assert.True(serverComponentDeserializer.TryDeserializeComponentDescriptorCollection(markers, out var descriptors)); | ||||||
| Assert.Equal(2, descriptors.Count); | ||||||
|
|
||||||
| var firstDescriptor = descriptors[0]; | ||||||
| Assert.Equal(typeof(GenericTestComponent<int>).FullName, firstDescriptor.ComponentType.FullName); | ||||||
| Assert.Equal(0, firstDescriptor.Sequence); | ||||||
|
|
||||||
| var secondDescriptor = descriptors[1]; | ||||||
| Assert.Equal(typeof(GenericTestComponent<string>).FullName, secondDescriptor.ComponentType.FullName); | ||||||
| Assert.Equal(0, secondDescriptor.Sequence); | ||||||
|
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.
|
||||||
| Assert.Equal(0, secondDescriptor.Sequence); | |
| Assert.Equal(1, secondDescriptor.Sequence); |
- Apply suggested fix
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.
In
CanPrerender_ClosedGenericComponent_ClientMode, the component is rendered asGenericComponent<int>with an integer value456, but the assertions on lines 837-838 check againsttypeof(GenericComponent<string>)for bothAssemblyandTypeName. This means the test is asserting the wrong type metadata:typeof(GenericComponent<int>)is used to rendertypeof(GenericComponent<string>).Assembly.GetName().Nameis used to asserttypeof(GenericComponent<string>).FullNameis used to assertSince both
GenericComponent<int>andGenericComponent<string>share the same assembly, the assembly assertion will pass coincidentally. However, theFullNameassertion will either fail (if the serialized marker correctly recordsGenericComponent<int>) or, if it passes, it means the test is validating the wrong expected value. Either way, these should usetypeof(GenericComponent<int>)to match the rendered component type.Was this helpful? React with 👍 / 👎