From ca712c18c73c04b0f659c031fba6abff99774267 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Tue, 7 May 2024 09:55:44 +0200 Subject: [PATCH 01/15] Commit modifies the InputNumber component to allow the 'type' attribute specified by the user to take precedence over the default 'type="number"'. By swapping the order in which attributes are added to the builder, any user-defined 'type' attribute is now respected, enabling the usage of different input types like 'range'. Previously, the InputNumber component hardcoded the 'type' attribute as 'number', which prevented using it for other input types such as sliders (range inputs). --- src/Components/Web/src/Forms/InputNumber.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Components/Web/src/Forms/InputNumber.cs b/src/Components/Web/src/Forms/InputNumber.cs index fa4d31c0708e..b346b4b39772 100644 --- a/src/Components/Web/src/Forms/InputNumber.cs +++ b/src/Components/Web/src/Forms/InputNumber.cs @@ -53,8 +53,8 @@ protected override void BuildRenderTree(RenderTreeBuilder builder) { builder.OpenElement(0, "input"); builder.AddAttribute(1, "step", _stepAttributeValue); - builder.AddMultipleAttributes(2, AdditionalAttributes); - builder.AddAttribute(3, "type", "number"); + builder.AddAttribute(2, "type", "number"); + builder.AddMultipleAttributes(3, AdditionalAttributes); builder.AddAttributeIfNotNullOrEmpty(4, "name", NameAttributeValue); builder.AddAttributeIfNotNullOrEmpty(5, "class", CssClass); builder.AddAttribute(6, "value", CurrentValueAsString); From f9ceb169194b20083b92f052c44771ec80209006 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Tue, 7 May 2024 14:56:18 +0200 Subject: [PATCH 02/15] Adding a test to the inputNumberTests to ensure the user defined type attribute overrides the default. --- .../Web/test/Forms/InputNumberTest.cs | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 793ce20af473..d08160bf27bc 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -49,6 +49,29 @@ public async Task InputElementIsAssignedSuccessfully() Assert.NotNull(inputSelectComponent.Element); } + [Fact] + public async Task UserDefinedTypeAttributeOverridesDefault() + { + // Arrange + var model = new TestModel(); + var rootComponent = new TestInputHostComponent + { + EditContext = new EditContext(model), + ValueExpression = () => model.SomeNumber, + AdditionalAttributes = new Dictionary + { + { "type", "range" } // User-defined 'type' attribute + } + }; + + // Act + var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); + var componentTypeName = inputComponent.Element.GetType().Name; + + // Assert + Assert.Equal("range", componentTypeName); + } + private class TestModel { public int SomeNumber { get; set; } From bfa7733b2ac08267264585d4a33f00d998d87d8e Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Tue, 7 May 2024 19:53:37 +0200 Subject: [PATCH 03/15] Using the TestRederer to extract attributes and assert the user-defined type override the default --- .../Web/test/Forms/InputNumberTest.cs | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index d08160bf27bc..d62299821507 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -1,6 +1,9 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Components.RenderTree; +using Microsoft.AspNetCore.Components.Test.Helpers; + namespace Microsoft.AspNetCore.Components.Forms; public class InputNumberTest @@ -59,17 +62,27 @@ public async Task UserDefinedTypeAttributeOverridesDefault() EditContext = new EditContext(model), ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary - { - { "type", "range" } // User-defined 'type' attribute - } + { + { "type", "range" } // User-defined 'type' attribute to override default + } }; // Act - var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); - var componentTypeName = inputComponent.Element.GetType().Name; + var testRenderer = new TestRenderer(); + var componentId = testRenderer.AssignRootComponentId(rootComponent); + await testRenderer.RenderRootComponentAsync(componentId); + + // Retrieve the render tree frames and extract attributes + var frames = testRenderer.GetCurrentRenderTreeFrames(componentId); + var attributes = frames.AsEnumerable() + .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element || frame.ElementName != "input") + .Skip(1) // Skip the input element frame itself + .TakeWhile(frame => frame.FrameType == RenderTreeFrameType.Attribute) + .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue.ToString()); // Assert - Assert.Equal("range", componentTypeName); + Assert.True(attributes.ContainsKey("type")); + Assert.Equal("range", attributes["type"]); } private class TestModel From 8df498d4c19cf49734e9e8e5b87c15137eaaf600 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Wed, 8 May 2024 10:56:34 +0200 Subject: [PATCH 04/15] Retrieving frames with new methodology --- src/Components/Web/test/Forms/InputNumberTest.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index d62299821507..91a3f8c177da 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -75,10 +75,9 @@ public async Task UserDefinedTypeAttributeOverridesDefault() // Retrieve the render tree frames and extract attributes var frames = testRenderer.GetCurrentRenderTreeFrames(componentId); var attributes = frames.AsEnumerable() - .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element || frame.ElementName != "input") - .Skip(1) // Skip the input element frame itself + .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element) .TakeWhile(frame => frame.FrameType == RenderTreeFrameType.Attribute) - .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue.ToString()); + .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue); // Assert Assert.True(attributes.ContainsKey("type")); From c7a76aff73a3aee16e4f2cb7327d1b3e01a23649 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Thu, 9 May 2024 13:55:38 +0200 Subject: [PATCH 05/15] Isolating the correct element to extract attributes from --- src/Components/Web/test/Forms/InputNumberTest.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 91a3f8c177da..54c65859ad6f 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -75,9 +75,10 @@ public async Task UserDefinedTypeAttributeOverridesDefault() // Retrieve the render tree frames and extract attributes var frames = testRenderer.GetCurrentRenderTreeFrames(componentId); var attributes = frames.AsEnumerable() - .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element) - .TakeWhile(frame => frame.FrameType == RenderTreeFrameType.Attribute) - .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue); + .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element || frame.ElementName != "input") + .Skip(1) + .TakeWhile(frame => frame.FrameType == RenderTreeFrameType.Attribute) + .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue); // Assert Assert.True(attributes.ContainsKey("type")); From ac09491aef6de46f38b6b7939ed64252ed6ea022 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Thu, 9 May 2024 14:17:35 +0200 Subject: [PATCH 06/15] Only asserting the type attribute = range --- src/Components/Web/test/Forms/InputNumberTest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 54c65859ad6f..7c56ffb93727 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -81,7 +81,6 @@ public async Task UserDefinedTypeAttributeOverridesDefault() .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue); // Assert - Assert.True(attributes.ContainsKey("type")); Assert.Equal("range", attributes["type"]); } From dd6b779cd4b784f050fbb4d84ea05dc647565867 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Tue, 14 May 2024 15:10:42 +0200 Subject: [PATCH 07/15] Isolating input element, atrributes and type attribute correctly --- .../Web/test/Forms/InputNumberTest.cs | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 7c56ffb93727..821c60cb9fb9 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -74,13 +74,32 @@ public async Task UserDefinedTypeAttributeOverridesDefault() // Retrieve the render tree frames and extract attributes var frames = testRenderer.GetCurrentRenderTreeFrames(componentId); - var attributes = frames.AsEnumerable() - .SkipWhile(frame => frame.FrameType != RenderTreeFrameType.Element || frame.ElementName != "input") - .Skip(1) - .TakeWhile(frame => frame.FrameType == RenderTreeFrameType.Attribute) - .ToDictionary(frame => frame.AttributeName, frame => frame.AttributeValue); + bool inputElementFound = false; + var attributes = new Dictionary(); + + for (int i = 0; i < frames.Count; i++) + { + var frame = frames.Array[i]; + if (frame.FrameType == RenderTreeFrameType.Element && frame.ElementName == "input") + { + inputElementFound = true; + // Start looking for attributes + for (int j = i + 1; j < frames.Count; j++) + { + var attributeFrame = frames.Array[j]; + if (attributeFrame.FrameType != RenderTreeFrameType.Attribute) + { + break; + } + attributes[attributeFrame.AttributeName] = attributeFrame.AttributeValue; + } + break; + } + } // Assert + Assert.True(inputElementFound, "Input element was not found."); + Assert.True(attributes.ContainsKey("type"), "Type attribute was not found."); Assert.Equal("range", attributes["type"]); } From 7b2ee01eae708daf35fb101c478d66e7da22812a Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Wed, 15 May 2024 20:23:00 +0200 Subject: [PATCH 08/15] Improving methodology of handling render tree frames and isolating the input element and attributes --- src/Components/Web/test/Forms/InputNumberTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 821c60cb9fb9..d7f580f30db3 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -83,7 +83,7 @@ public async Task UserDefinedTypeAttributeOverridesDefault() if (frame.FrameType == RenderTreeFrameType.Element && frame.ElementName == "input") { inputElementFound = true; - // Start looking for attributes + // Collect attributes for the input element for (int j = i + 1; j < frames.Count; j++) { var attributeFrame = frames.Array[j]; From ebf82de4b7c6e02058476fabbab367babfd6bb9d Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Mon, 20 May 2024 18:10:26 +0200 Subject: [PATCH 09/15] Ammendments to tests --- .../Web/test/Forms/InputNumberTest.cs | 85 ++++++++----------- 1 file changed, 35 insertions(+), 50 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index d7f580f30db3..8fa3b521261d 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -1,55 +1,23 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using Microsoft.AspNetCore.Components.Forms.Mapping; +using Microsoft.AspNetCore.Components.Infrastructure; using Microsoft.AspNetCore.Components.RenderTree; using Microsoft.AspNetCore.Components.Test.Helpers; +using Microsoft.Extensions.DependencyInjection; namespace Microsoft.AspNetCore.Components.Forms; -public class InputNumberTest +public class InputNumberTests { - [Fact] - public async Task ValidationErrorUsesDisplayAttributeName() - { - // Arrange - var model = new TestModel(); - var rootComponent = new TestInputHostComponent - { - EditContext = new EditContext(model), - ValueExpression = () => model.SomeNumber, - AdditionalAttributes = new Dictionary - { - { "DisplayName", "Some number" } - } - }; - var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber); - var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); - - // Act - await inputComponent.SetCurrentValueAsStringAsync("notANumber"); - - // Assert - var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier); - Assert.NotEmpty(validationMessages); - Assert.Contains("The Some number field must be a number.", validationMessages); - } + private TestRenderer _testRenderer; - [Fact] - public async Task InputElementIsAssignedSuccessfully() + public InputNumberTests() { - // Arrange - var model = new TestModel(); - var rootComponent = new TestInputHostComponent - { - EditContext = new EditContext(model), - ValueExpression = () => model.SomeNumber, - }; - - // Act - var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent); - - // Assert - Assert.NotNull(inputSelectComponent.Element); + var services = new ServiceCollection(); + services.AddLogging(); + _testRenderer = new TestRenderer(services.BuildServiceProvider()); } [Fact] @@ -57,23 +25,28 @@ public async Task UserDefinedTypeAttributeOverridesDefault() { // Arrange var model = new TestModel(); - var rootComponent = new TestInputHostComponent + var hostComponent = new TestInputHostComponent { EditContext = new EditContext(model), ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary - { - { "type", "range" } // User-defined 'type' attribute to override default - } + { + { "type", "range" } // User-defined 'type' attribute to override default + } }; // Act - var testRenderer = new TestRenderer(); - var componentId = testRenderer.AssignRootComponentId(rootComponent); - await testRenderer.RenderRootComponentAsync(componentId); + var componentId = await RenderAndGetTestInputNumberComponentIdAsync(hostComponent); // Retrieve the render tree frames and extract attributes - var frames = testRenderer.GetCurrentRenderTreeFrames(componentId); + var frames = _testRenderer.GetCurrentRenderTreeFrames(componentId); + + // Debugging: Output the frames for inspection + foreach (var frame in frames.Array) + { + Console.WriteLine($"Frame: {frame.FrameType}, {frame.ElementName}, {frame.AttributeName}, {frame.AttributeValue}"); + } + bool inputElementFound = false; var attributes = new Dictionary(); @@ -83,7 +56,6 @@ public async Task UserDefinedTypeAttributeOverridesDefault() if (frame.FrameType == RenderTreeFrameType.Element && frame.ElementName == "input") { inputElementFound = true; - // Collect attributes for the input element for (int j = i + 1; j < frames.Count; j++) { var attributeFrame = frames.Array[j]; @@ -103,6 +75,19 @@ public async Task UserDefinedTypeAttributeOverridesDefault() Assert.Equal("range", attributes["type"]); } + private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent hostComponent) + { + var componentId = _testRenderer.AssignRootComponentId(hostComponent); + await _testRenderer.RenderRootComponentAsync(componentId); + return FindTestInputNumberComponentId(_testRenderer.Batches.Single(), typeof(TestInputNumberComponent)); + } + + private static int FindTestInputNumberComponentId(CapturedBatch batch, Type componentType) + => batch.ReferenceFrames + .Where(f => f.FrameType == RenderTreeFrameType.Component && f.Component.GetType() == componentType) + .Select(f => f.ComponentId) + .Single(); + private class TestModel { public int SomeNumber { get; set; } From b1ab8e0e3d26201263d3aab921d93764abdca76d Mon Sep 17 00:00:00 2001 From: Matthew Leslie <67387027+MattyLeslie@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:54:43 +0200 Subject: [PATCH 10/15] Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck --- src/Components/Web/test/Forms/InputNumberTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 8fa3b521261d..8da8a616d69f 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -9,7 +9,7 @@ namespace Microsoft.AspNetCore.Components.Forms; -public class InputNumberTests +public class InputNumberTest { private TestRenderer _testRenderer; From bf707423d3f4e16513fd5d099e175770dee3d9a3 Mon Sep 17 00:00:00 2001 From: Matthew Leslie <67387027+MattyLeslie@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:54:50 +0200 Subject: [PATCH 11/15] Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck --- src/Components/Web/test/Forms/InputNumberTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 8da8a616d69f..843c1e2df234 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -13,7 +13,7 @@ public class InputNumberTest { private TestRenderer _testRenderer; - public InputNumberTests() + public InputNumberTest() { var services = new ServiceCollection(); services.AddLogging(); From abfb3e6b487edd426d12047e671758112843a378 Mon Sep 17 00:00:00 2001 From: Matthew Leslie <67387027+MattyLeslie@users.noreply.github.com> Date: Fri, 26 Jul 2024 08:54:57 +0200 Subject: [PATCH 12/15] Update src/Components/Web/test/Forms/InputNumberTest.cs Co-authored-by: Mackinnon Buck --- src/Components/Web/test/Forms/InputNumberTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 843c1e2df234..514f9eb12be1 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -11,7 +11,7 @@ namespace Microsoft.AspNetCore.Components.Forms; public class InputNumberTest { - private TestRenderer _testRenderer; + private readonly TestRenderer _testRenderer; public InputNumberTest() { From 11aa774f1873ff08235d680a80225fa75ba618a5 Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Fri, 26 Jul 2024 10:59:32 +0200 Subject: [PATCH 13/15] re-adding missing tests --- .../Web/test/Forms/InputNumberTest.cs | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 514f9eb12be1..ab3a927ccda1 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -20,6 +20,50 @@ public InputNumberTest() _testRenderer = new TestRenderer(services.BuildServiceProvider()); } + [Fact] + public async Task ValidationErrorUsesDisplayAttributeName() + { + // Arrange + var model = new TestModel(); + var rootComponent = new TestInputHostComponent + { + EditContext = new EditContext(model), + ValueExpression = () => model.SomeNumber, + AdditionalAttributes = new Dictionary + { + { "DisplayName", "Some number" } + } + }; + var fieldIdentifier = FieldIdentifier.Create(() => model.SomeNumber); + var inputComponent = await InputRenderer.RenderAndGetComponent(rootComponent); + + // Act + await inputComponent.SetCurrentValueAsStringAsync("notANumber"); + + // Assert + var validationMessages = rootComponent.EditContext.GetValidationMessages(fieldIdentifier); + Assert.NotEmpty(validationMessages); + Assert.Contains("The Some number field must be a number.", validationMessages); + } + + [Fact] + public async Task InputElementIsAssignedSuccessfully() + { + // Arrange + var model = new TestModel(); + var rootComponent = new TestInputHostComponent + { + EditContext = new EditContext(model), + ValueExpression = () => model.SomeNumber, + }; + + // Act + var inputSelectComponent = await InputRenderer.RenderAndGetComponent(rootComponent); + + // Assert + Assert.NotNull(inputSelectComponent.Element); + } + [Fact] public async Task UserDefinedTypeAttributeOverridesDefault() { From 6e7ca9401794fbe03a4d0d0c76fd304770cf7f2a Mon Sep 17 00:00:00 2001 From: MattyLeslie Date: Fri, 26 Jul 2024 11:16:48 +0200 Subject: [PATCH 14/15] Using helper methods in tests. --- .../Web/test/Forms/InputNumberTest.cs | 55 ++++--------------- 1 file changed, 12 insertions(+), 43 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index ab3a927ccda1..1a3f151d83d9 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -74,64 +74,33 @@ public async Task UserDefinedTypeAttributeOverridesDefault() EditContext = new EditContext(model), ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary - { - { "type", "range" } // User-defined 'type' attribute to override default - } + { + { "type", "range" } // User-defined 'type' attribute to override default + } }; // Act var componentId = await RenderAndGetTestInputNumberComponentIdAsync(hostComponent); - // Retrieve the render tree frames and extract attributes + // Retrieve the render tree frames and extract attributes using helper methods var frames = _testRenderer.GetCurrentRenderTreeFrames(componentId); - // Debugging: Output the frames for inspection - foreach (var frame in frames.Array) - { - Console.WriteLine($"Frame: {frame.FrameType}, {frame.ElementName}, {frame.AttributeName}, {frame.AttributeValue}"); - } - - bool inputElementFound = false; - var attributes = new Dictionary(); - - for (int i = 0; i < frames.Count; i++) - { - var frame = frames.Array[i]; - if (frame.FrameType == RenderTreeFrameType.Element && frame.ElementName == "input") - { - inputElementFound = true; - for (int j = i + 1; j < frames.Count; j++) - { - var attributeFrame = frames.Array[j]; - if (attributeFrame.FrameType != RenderTreeFrameType.Attribute) - { - break; - } - attributes[attributeFrame.AttributeName] = attributeFrame.AttributeValue; - } - break; - } - } + var typeAttributeFrame = frames.Array.Single(frame => + frame.FrameType == RenderTreeFrameType.Attribute && + frame.AttributeName == "type"); // Assert - Assert.True(inputElementFound, "Input element was not found."); - Assert.True(attributes.ContainsKey("type"), "Type attribute was not found."); - Assert.Equal("range", attributes["type"]); + Assert.Equal("range", typeAttributeFrame.AttributeValue); } private async Task RenderAndGetTestInputNumberComponentIdAsync(TestInputHostComponent hostComponent) { - var componentId = _testRenderer.AssignRootComponentId(hostComponent); - await _testRenderer.RenderRootComponentAsync(componentId); - return FindTestInputNumberComponentId(_testRenderer.Batches.Single(), typeof(TestInputNumberComponent)); + var hostComponentId = _testRenderer.AssignRootComponentId(hostComponent); + await _testRenderer.RenderRootComponentAsync(hostComponentId); + var batch = _testRenderer.Batches.Single(); + return batch.GetComponentFrames().Single().ComponentId; } - private static int FindTestInputNumberComponentId(CapturedBatch batch, Type componentType) - => batch.ReferenceFrames - .Where(f => f.FrameType == RenderTreeFrameType.Component && f.Component.GetType() == componentType) - .Select(f => f.ComponentId) - .Single(); - private class TestModel { public int SomeNumber { get; set; } From c717209a739de68eccb9f62dff3c0d383c2aa2ca Mon Sep 17 00:00:00 2001 From: Mackinnon Buck Date: Fri, 26 Jul 2024 09:21:39 -0700 Subject: [PATCH 15/15] Update src/Components/Web/test/Forms/InputNumberTest.cs --- src/Components/Web/test/Forms/InputNumberTest.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Components/Web/test/Forms/InputNumberTest.cs b/src/Components/Web/test/Forms/InputNumberTest.cs index 1a3f151d83d9..12a7891b4bb4 100644 --- a/src/Components/Web/test/Forms/InputNumberTest.cs +++ b/src/Components/Web/test/Forms/InputNumberTest.cs @@ -74,9 +74,9 @@ public async Task UserDefinedTypeAttributeOverridesDefault() EditContext = new EditContext(model), ValueExpression = () => model.SomeNumber, AdditionalAttributes = new Dictionary - { - { "type", "range" } // User-defined 'type' attribute to override default - } + { + { "type", "range" } // User-defined 'type' attribute to override default + } }; // Act