diff --git a/sample/tests/Tests/Components/FocussingInputTest.cs b/sample/tests/Tests/Components/FocussingInputTest.cs
index eaac8ba87..bc84d316b 100644
--- a/sample/tests/Tests/Components/FocussingInputTest.cs
+++ b/sample/tests/Tests/Components/FocussingInputTest.cs
@@ -6,6 +6,7 @@
using Egil.RazorComponents.Testing.Asserting;
using Egil.RazorComponents.Testing.Mocking.JSInterop;
using Egil.RazorComponents.Testing.SampleApp.Components;
+using Egil.RazorComponents.Testing.Mocking.JSInterop;
using Xunit;
namespace Egil.RazorComponents.Testing.SampleApp.CodeOnlyTests.Components
diff --git a/sample/tests/Tests/Components/TodoListTest.cs b/sample/tests/Tests/Components/TodoListTest.cs
index 34b4ac5b2..a0946c64b 100644
--- a/sample/tests/Tests/Components/TodoListTest.cs
+++ b/sample/tests/Tests/Components/TodoListTest.cs
@@ -3,6 +3,7 @@
using Egil.RazorComponents.Testing.Asserting;
using Egil.RazorComponents.Testing.Mocking.JSInterop;
using Egil.RazorComponents.Testing.EventDispatchExtensions;
+using Egil.RazorComponents.Testing.Mocking.JSInterop;
using Egil.RazorComponents.Testing.SampleApp.Components;
using Egil.RazorComponents.Testing.SampleApp.Data;
using Microsoft.AspNetCore.Components;
diff --git a/src/Components/ContainerComponent.cs b/src/Components/ContainerComponent.cs
index 6a9092469..7a789580f 100644
--- a/src/Components/ContainerComponent.cs
+++ b/src/Components/ContainerComponent.cs
@@ -7,6 +7,7 @@
using System.Linq;
using System.Threading.Tasks;
using Egil.RazorComponents.Testing.Extensions;
+using AngleSharp.Css.Dom;
namespace Egil.RazorComponents.Testing
{
@@ -32,7 +33,7 @@ public ContainerComponent(TestRenderer renderer)
{
if (renderer is null) throw new ArgumentNullException(nameof(renderer));
_renderer = renderer;
- ComponentId = _renderer.AttachTestRootComponent(this);
+ ComponentId = _renderer.AttachTestRootComponent(this);
}
///
@@ -58,17 +59,14 @@ public void Render(RenderFragment renderFragment)
/// component is found, its child content is also searched recursively.
///
/// The type of component to find
- /// When there are more than one component of type found or if none are found.
+ /// When a component of type was not found.
public (int Id, TComponent Component) GetComponent() where TComponent : IComponent
{
- var result = GetComponents();
-
- if (result.Count == 1)
- return result[0];
- else if (result.Count == 0)
- throw new InvalidOperationException($"No components of type {typeof(TComponent)} were found in the render tree.");
+ var result = GetComponent(ComponentId);
+ if (result.HasValue)
+ return result.Value;
else
- throw new InvalidOperationException($"More than one component of type {typeof(TComponent)} was found in the render tree.");
+ throw new InvalidOperationException($"No components of type {typeof(TComponent)} were found in the render tree.");
}
///
@@ -84,7 +82,7 @@ public void Render(RenderFragment renderFragment)
var ownFrames = _renderer.GetCurrentRenderTreeFrames(componentId);
if (ownFrames.Count == 0)
{
- throw new InvalidOperationException($"{nameof(ContainerComponent)} hasn't yet rendered");
+ return Array.Empty<(int Id, TComponent Component)>();
}
var result = new List<(int Id, TComponent Component)>();
@@ -97,20 +95,32 @@ public void Render(RenderFragment renderFragment)
{
result.Add((frame.ComponentId, component));
}
- else if (frame.Component.IsCascadingValueComponent())
+ result.AddRange(GetComponents(frame.ComponentId));
+ }
+ }
+
+ return result;
+ }
+
+ private (int Id, TComponent Component)? GetComponent(int componentId) where TComponent : IComponent
+ {
+ var ownFrames = _renderer.GetCurrentRenderTreeFrames(componentId);
+
+ for (int i = 0; i < ownFrames.Count; i++)
+ {
+ ref var frame = ref ownFrames.Array[i];
+ if (frame.FrameType == RenderTreeFrameType.Component)
+ {
+ if (frame.Component is TComponent component)
{
- // It seems as if CascadingValue components works a little different
- // than regular components with child content is not rendered
- // and available via GetCurrentRenderTreeFrames for the componentId
- // of the component that had the CascadingValue as a child.
- // Thus we call GetComponents recursively with the CascadingValue's
- // componentId to see if the TComponent is inside it.
- result.AddRange(GetComponents(frame.ComponentId));
+ return (frame.ComponentId, component);
}
+ var result = GetComponent(frame.ComponentId);
+ if (result != null) return result;
}
}
- return result;
+ return null;
}
}
}
diff --git a/src/Egil.RazorComponents.Testing.Library.csproj b/src/Egil.RazorComponents.Testing.Library.csproj
index 77e01d21a..a25b4cb6a 100644
--- a/src/Egil.RazorComponents.Testing.Library.csproj
+++ b/src/Egil.RazorComponents.Testing.Library.csproj
@@ -51,7 +51,7 @@ This library's goal is to make it easy to write comprehensive, stable unit tests
-
+
diff --git a/src/ElementNotFoundException.cs b/src/ElementNotFoundException.cs
index 1a3caf9fe..a4792322c 100644
--- a/src/ElementNotFoundException.cs
+++ b/src/ElementNotFoundException.cs
@@ -5,7 +5,7 @@
using System.Text;
using System.Threading.Tasks;
-namespace Egil.RazorComponents.Testing
+namespace Xunit.Sdk
{
///
/// Represents a failure to find an element in the searched target
diff --git a/src/Rendering/IRenderedFragment.cs b/src/Rendering/IRenderedFragment.cs
index 9742bb918..7ddc8af4c 100644
--- a/src/Rendering/IRenderedFragment.cs
+++ b/src/Rendering/IRenderedFragment.cs
@@ -3,6 +3,7 @@
using System.Linq;
using AngleSharp.Diffing.Core;
using AngleSharp.Dom;
+using Xunit.Sdk;
namespace Egil.RazorComponents.Testing
{
diff --git a/src/Rendering/RenderedFragmentBase.cs b/src/Rendering/RenderedFragmentBase.cs
index e02050b5b..8801b371b 100644
--- a/src/Rendering/RenderedFragmentBase.cs
+++ b/src/Rendering/RenderedFragmentBase.cs
@@ -93,7 +93,6 @@ public IReadOnlyList GetChangesSinceSnapshot()
return Nodes.CompareTo(_snapshotNodes);
}
-
///
public IReadOnlyList GetChangesSinceFirstRender()
{
@@ -104,24 +103,30 @@ public IReadOnlyList GetChangesSinceFirstRender()
private void ComponentMarkupChanged(in RenderBatch renderBatch)
{
- if (renderBatch.HasUpdatesTo(ComponentId) || HasChildComponentUpdated(renderBatch))
+ if (renderBatch.HasUpdatesTo(ComponentId) || HasChildComponentUpdated(renderBatch, ComponentId))
{
ResetLatestRenderCache();
}
}
- private bool HasChildComponentUpdated(in RenderBatch renderBatch)
+ private bool HasChildComponentUpdated(in RenderBatch renderBatch, int componentId)
{
- var frames = TestContext.Renderer.GetCurrentRenderTreeFrames(ComponentId);
+ var frames = TestContext.Renderer.GetCurrentRenderTreeFrames(componentId);
+
for (int i = 0; i < frames.Count; i++)
{
var frame = frames.Array[i];
-
- if (renderBatch.HasUpdatesTo(frame.ComponentId))
+ if (frame.FrameType == RenderTreeFrameType.Component)
{
- return true;
+ if (renderBatch.HasUpdatesTo(frame.ComponentId))
+ {
+ return true;
+ }
+ if (HasChildComponentUpdated(in renderBatch, frame.ComponentId))
+ {
+ return true;
+ }
}
-
}
return false;
}
diff --git a/tests/Components/TestComponentBaseTest/BlazorElementReferencesIncludedInRenderedMarkup.razor b/tests/Components/TestComponentBaseTest/BlazorElementReferencesIncludedInRenderedMarkup.razor
index 3133f8108..b74d0f841 100644
--- a/tests/Components/TestComponentBaseTest/BlazorElementReferencesIncludedInRenderedMarkup.razor
+++ b/tests/Components/TestComponentBaseTest/BlazorElementReferencesIncludedInRenderedMarkup.razor
@@ -1,6 +1,5 @@
@inherits TestComponentBase
-
diff --git a/tests/RenderComponentTest.cs b/tests/RenderComponentTest.cs
index 33379530d..e9bd2cb64 100644
--- a/tests/RenderComponentTest.cs
+++ b/tests/RenderComponentTest.cs
@@ -22,7 +22,7 @@ public void Test003()
[Fact(DisplayName = "Nodes should return new instance " +
"when a SetParametersAndRender has caused changes to DOM tree")]
- public void Tets004()
+ public void Test004()
{
var cut = RenderComponent(ChildContent("
"));
var initialNodes = cut.Nodes;
@@ -35,7 +35,7 @@ public void Tets004()
[Fact(DisplayName = "Nodes should return new instance " +
"when a Render has caused changes to DOM tree")]
- public void Tets005()
+ public void Test005()
{
var cut = RenderComponent();
var initialNodes = cut.Nodes;
@@ -44,20 +44,5 @@ public void Tets005()
Assert.NotSame(initialNodes, cut.Nodes);
}
-
- [Fact(DisplayName = "Nodes should return new instance " +
- "when a event handler trigger has caused changes to DOM tree")]
- public void Tets006()
- {
- var cut = RenderComponent();
- var initialNodes = cut.Nodes;
-
- cut.Find("button").Click();
-
- Assert.NotSame(initialNodes, cut.Nodes);
- }
-
-
}
-
}
diff --git a/tests/RenderedFragmentTest.cs b/tests/RenderedFragmentTest.cs
index ac8075e5e..2ca8f452e 100644
--- a/tests/RenderedFragmentTest.cs
+++ b/tests/RenderedFragmentTest.cs
@@ -1,6 +1,8 @@
-using Egil.RazorComponents.Testing.Extensions;
+using Egil.RazorComponents.Testing.EventDispatchExtensions;
+using Egil.RazorComponents.Testing.Extensions;
using Egil.RazorComponents.Testing.SampleComponents;
using Egil.RazorComponents.Testing.SampleComponents.Data;
+using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.DependencyInjection;
using Shouldly;
using System;
@@ -8,6 +10,7 @@
using System.Linq;
using System.Text;
using Xunit;
+using Xunit.Sdk;
namespace Egil.RazorComponents.Testing
{
@@ -70,6 +73,51 @@ public void Test005()
Assert.NotSame(initialValue, cut.Nodes);
}
+
+
+ [Fact(DisplayName = "Nodes should return new instance " +
+ "when a event handler trigger has caused changes to DOM tree")]
+ public void Test006()
+ {
+ var cut = RenderComponent();
+ var initialNodes = cut.Nodes;
+
+ cut.Find("button").Click();
+
+ Assert.NotSame(initialNodes, cut.Nodes);
+ }
+
+ [Fact(DisplayName = "Nodes should return new instance " +
+ "when a nested component has caused the DOM tree to change")]
+ public void Test007()
+ {
+ var cut = RenderComponent(
+ ChildContent>(
+ ("Value", "FOO"),
+ ChildContent()
+ )
+ );
+ var initialNodes = cut.Nodes;
+
+ cut.Find("button").Click();
+
+ Assert.NotSame(initialNodes, cut.Nodes);
+ }
+
+ [Fact(DisplayName = "Nodes should return the same instance " +
+ "when a re-render does not causes the DOM to change")]
+ public void Test008()
+ {
+ var cut = RenderComponent();
+ var initialNodes = cut.Nodes;
+
+ cut.Find("button").Click();
+
+ cut.Instance.RenderCount.ShouldBe(2);
+ Assert.Same(initialNodes, cut.Nodes);
+ }
+
+
}
}
diff --git a/tests/SampleComponents/RenderOnClick.razor b/tests/SampleComponents/RenderOnClick.razor
new file mode 100644
index 000000000..d5ed71b16
--- /dev/null
+++ b/tests/SampleComponents/RenderOnClick.razor
@@ -0,0 +1,9 @@
+
+
+@code {
+ public int RenderCount { get; private set; }
+
+ void IncreaseCount() { }
+
+ protected override void OnAfterRender(bool firstRender) => RenderCount++;
+}
\ No newline at end of file
diff --git a/tests/_Imports.razor b/tests/_Imports.razor
index 94baed4ea..7c7ad8e8b 100644
--- a/tests/_Imports.razor
+++ b/tests/_Imports.razor
@@ -1,5 +1,9 @@
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.Extensions.DependencyInjection
+@using Egil.RazorComponents.Testing
+@using Egil.RazorComponents.Testing.Asserting
+@using Egil.RazorComponents.Testing.EventDispatchExtensions
+@using Egil.RazorComponents.Testing.Mocking.JSInterop
@using Egil.RazorComponents.Testing.SampleComponents
@using Egil.RazorComponents.Testing.SampleComponents.Data
@using Shouldly