Replace "DescendantsEndIndex" concept with "SubtreeLength"

In other words, use relative addressing so that frame data is
independent of its position in the array
This commit is contained in:
Steve Sanderson 2018-02-06 22:12:02 +00:00
parent c4412c9739
commit 33932f41fc
10 changed files with 79 additions and 74 deletions

View File

@ -115,15 +115,15 @@ export class BrowserRenderer {
insertNodeIntoDOM(newDomElement, parent, childIndex); insertNodeIntoDOM(newDomElement, parent, childIndex);
// Apply attributes // Apply attributes
const descendantsEndIndex = renderTreeFrame.descendantsEndIndex(frame); const descendantsEndIndexExcl = frameIndex + renderTreeFrame.subtreeLength(frame);
for (let descendantIndex = frameIndex + 1; descendantIndex <= descendantsEndIndex; descendantIndex++) { for (let descendantIndex = frameIndex + 1; descendantIndex < descendantsEndIndexExcl; descendantIndex++) {
const descendantFrame = getTreeFramePtr(frames, descendantIndex); const descendantFrame = getTreeFramePtr(frames, descendantIndex);
if (renderTreeFrame.frameType(descendantFrame) === FrameType.attribute) { if (renderTreeFrame.frameType(descendantFrame) === FrameType.attribute) {
this.applyAttribute(componentId, newDomElement, descendantFrame, descendantIndex); this.applyAttribute(componentId, newDomElement, descendantFrame, descendantIndex);
} else { } else {
// As soon as we see a non-attribute child, all the subsequent child frames are // As soon as we see a non-attribute child, all the subsequent child frames are
// not attributes, so bail out and insert the remnants recursively // not attributes, so bail out and insert the remnants recursively
this.insertFrameRange(componentId, newDomElement, 0, frames, descendantIndex, descendantsEndIndex); this.insertFrameRange(componentId, newDomElement, 0, frames, descendantIndex, descendantsEndIndexExcl);
break; break;
} }
} }
@ -197,16 +197,16 @@ export class BrowserRenderer {
} }
} }
insertFrameRange(componentId: number, parent: Element, childIndex: number, frames: System_Array<RenderTreeFramePointer>, startIndex: number, endIndex: number) { insertFrameRange(componentId: number, parent: Element, childIndex: number, frames: System_Array<RenderTreeFramePointer>, startIndex: number, endIndexExcl: number) {
for (let index = startIndex; index <= endIndex; index++) { for (let index = startIndex; index < endIndexExcl; index++) {
const frame = getTreeFramePtr(frames, index); const frame = getTreeFramePtr(frames, index);
this.insertFrame(componentId, parent, childIndex, frames, frame, index); this.insertFrame(componentId, parent, childIndex, frames, frame, index);
childIndex++; childIndex++;
// Skip over any descendants, since they are already dealt with recursively // Skip over any descendants, since they are already dealt with recursively
const descendantsEndIndex = renderTreeFrame.descendantsEndIndex(frame); const subtreeLength = renderTreeFrame.subtreeLength(frame);
if (descendantsEndIndex > 0) { if (subtreeLength > 1) {
index = descendantsEndIndex; index += subtreeLength - 1;
} }
} }
} }

View File

@ -13,7 +13,7 @@ export function getTreeFramePtr(renderTreeEntries: System_Array<RenderTreeFrameP
export const renderTreeFrame = { export const renderTreeFrame = {
// The properties and memory layout must be kept in sync with the .NET equivalent in RenderTreeFrame.cs // The properties and memory layout must be kept in sync with the .NET equivalent in RenderTreeFrame.cs
frameType: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 4) as FrameType, frameType: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 4) as FrameType,
descendantsEndIndex: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 8) as FrameType, subtreeLength: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 8) as FrameType,
componentId: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 12), componentId: (frame: RenderTreeFramePointer) => platform.readInt32Field(frame, 12),
elementName: (frame: RenderTreeFramePointer) => platform.readStringField(frame, 16), elementName: (frame: RenderTreeFramePointer) => platform.readStringField(frame, 16),
textContent: (frame: RenderTreeFramePointer) => platform.readStringField(frame, 16), textContent: (frame: RenderTreeFramePointer) => platform.readStringField(frame, 16),

View File

@ -49,7 +49,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
{ {
var indexOfEntryBeingClosed = _openElementIndices.Pop(); var indexOfEntryBeingClosed = _openElementIndices.Pop();
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed]; ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
entry = entry.WithElementDescendantsEndIndex(_entries.Count - 1); entry = entry.WithElementSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
} }
/// <summary> /// <summary>
@ -60,7 +60,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
{ {
var indexOfEntryBeingClosed = _openElementIndices.Pop(); var indexOfEntryBeingClosed = _openElementIndices.Pop();
ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed]; ref var entry = ref _entries.Buffer[indexOfEntryBeingClosed];
entry = entry.WithComponentDescendantsEndIndex(_entries.Count - 1); entry = entry.WithComponentSubtreeLength(_entries.Count - indexOfEntryBeingClosed);
} }
/// <summary> /// <summary>

View File

@ -202,10 +202,10 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
// Now locate any added/changed/removed properties // Now locate any added/changed/removed properties
var oldStartIndex = oldComponentIndex + 1; var oldStartIndex = oldComponentIndex + 1;
var newStartIndex = newComponentIndex + 1; var newStartIndex = newComponentIndex + 1;
var oldEndIndexIncl = oldComponentFrame.ElementDescendantsEndIndex; var oldEndIndexExcl = oldComponentIndex + oldComponentFrame.ComponentSubtreeLength;
var newEndIndexIncl = newComponentFrame.ElementDescendantsEndIndex; var newEndIndexExcl = newComponentIndex + newComponentFrame.ComponentSubtreeLength;
var hasMoreOld = oldEndIndexIncl >= oldStartIndex; var hasMoreOld = oldEndIndexExcl > oldStartIndex;
var hasMoreNew = newEndIndexIncl >= newStartIndex; var hasMoreNew = newEndIndexExcl > newStartIndex;
while (hasMoreOld || hasMoreNew) while (hasMoreOld || hasMoreNew)
{ {
var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue; var oldSeq = hasMoreOld ? oldTree[oldStartIndex].Sequence : int.MaxValue;
@ -240,8 +240,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
oldStartIndex++; oldStartIndex++;
newStartIndex++; newStartIndex++;
hasMoreOld = oldEndIndexIncl >= oldStartIndex; hasMoreOld = oldEndIndexExcl > oldStartIndex;
hasMoreNew = newEndIndexIncl >= newStartIndex; hasMoreNew = newEndIndexExcl > newStartIndex;
} }
else else
{ {
@ -256,7 +256,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
SetChildComponentProperty(componentInstance, newFrame.AttributeName, newFrame.AttributeValue); SetChildComponentProperty(componentInstance, newFrame.AttributeName, newFrame.AttributeValue);
hasSetAnyProperty = true; hasSetAnyProperty = true;
newStartIndex++; newStartIndex++;
hasMoreNew = newEndIndexIncl >= newStartIndex; hasMoreNew = newEndIndexExcl > newStartIndex;
} }
else else
{ {
@ -264,7 +264,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
RemoveChildComponentProperty(componentInstance, oldFrame.AttributeName); RemoveChildComponentProperty(componentInstance, oldFrame.AttributeName);
hasSetAnyProperty = true; hasSetAnyProperty = true;
oldStartIndex++; oldStartIndex++;
hasMoreOld = oldEndIndexIncl >= oldStartIndex; hasMoreOld = oldEndIndexExcl > oldStartIndex;
} }
} }
} }
@ -312,10 +312,13 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
return property; return property;
} }
private static int NextSiblingIndex(in RenderTreeFrame frame, int frameIndex) private static int NextSiblingIndex(RenderTreeFrame frame, int frameIndex)
{ {
var descendantsEndIndex = frame.ElementDescendantsEndIndex; var subtreeLength = frame.ElementSubtreeLength;
return (descendantsEndIndex == 0 ? frameIndex : descendantsEndIndex) + 1; var distanceToNextSibling = subtreeLength == 0
? 1 // For frames that don't have a subtree length set, such as text frames
: subtreeLength; // For element or component frames
return frameIndex + distanceToNextSibling;
} }
private void AppendDiffEntriesForFramesWithSameSequence( private void AppendDiffEntriesForFramesWithSameSequence(
@ -360,8 +363,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
ref siblingIndex); ref siblingIndex);
// Diff the children // Diff the children
var oldFrameChildrenEndIndexExcl = oldFrame.ElementDescendantsEndIndex + 1; var oldFrameChildrenEndIndexExcl = oldFrameIndex + oldFrame.ElementSubtreeLength;
var newFrameChildrenEndIndexExcl = newFrame.ElementDescendantsEndIndex + 1; var newFrameChildrenEndIndexExcl = newFrameIndex + newFrame.ElementSubtreeLength;
var hasChildrenToProcess = var hasChildrenToProcess =
oldFrameChildrenEndIndexExcl > oldFrameAttributesEndIndexExcl || oldFrameChildrenEndIndexExcl > oldFrameAttributesEndIndexExcl ||
newFrameChildrenEndIndexExcl > newFrameAttributesEndIndexExcl; newFrameChildrenEndIndexExcl > newFrameAttributesEndIndexExcl;
@ -450,9 +453,9 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
private int GetAttributesEndIndexExclusive(RenderTreeFrame[] tree, int rootIndex) private int GetAttributesEndIndexExclusive(RenderTreeFrame[] tree, int rootIndex)
{ {
var descendantsEndIndex = tree[rootIndex].ElementDescendantsEndIndex; var descendantsEndIndexExcl = rootIndex + tree[rootIndex].ElementSubtreeLength;
var index = rootIndex + 1; var index = rootIndex + 1;
for (; index <= descendantsEndIndex; index++) for (; index < descendantsEndIndexExcl; index++)
{ {
if (tree[index].FrameType != RenderTreeFrameType.Attribute) if (tree[index].FrameType != RenderTreeFrameType.Attribute)
{ {
@ -481,8 +484,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
private void InstantiateChildComponents(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int elementOrComponentIndex) private void InstantiateChildComponents(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int elementOrComponentIndex)
{ {
var endIndex = frames[elementOrComponentIndex].ElementDescendantsEndIndex; var endIndexExcl = elementOrComponentIndex + frames[elementOrComponentIndex].ElementSubtreeLength;
for (var i = elementOrComponentIndex; i <= endIndex; i++) for (var i = elementOrComponentIndex; i < endIndexExcl; i++)
{ {
ref var frame = ref frames[i]; ref var frame = ref frames[i];
if (frame.FrameType == RenderTreeFrameType.Component) if (frame.FrameType == RenderTreeFrameType.Component)
@ -496,8 +499,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
var childComponentInstance = frame.Component; var childComponentInstance = frame.Component;
// All descendants of a component are its properties // All descendants of a component are its properties
var componentDescendantsEndIndex = frame.ElementDescendantsEndIndex; var componentDescendantsEndIndexExcl = i + frame.ComponentSubtreeLength;
for (var attributeFrameIndex = i + 1; attributeFrameIndex <= componentDescendantsEndIndex; attributeFrameIndex++) for (var attributeFrameIndex = i + 1; attributeFrameIndex < componentDescendantsEndIndexExcl; attributeFrameIndex++)
{ {
ref var attributeFrame = ref frames[attributeFrameIndex]; ref var attributeFrame = ref frames[attributeFrameIndex];
SetChildComponentProperty( SetChildComponentProperty(
@ -530,8 +533,8 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
private void DisposeChildComponents(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int elementOrComponentIndex) private void DisposeChildComponents(RenderBatchBuilder batchBuilder, RenderTreeFrame[] frames, int elementOrComponentIndex)
{ {
var endIndex = frames[elementOrComponentIndex].ElementDescendantsEndIndex; var endIndexExcl = elementOrComponentIndex + frames[elementOrComponentIndex].ElementSubtreeLength;
for (var i = elementOrComponentIndex; i <= endIndex; i++) for (var i = elementOrComponentIndex; i < endIndexExcl; i++)
{ {
ref var frame = ref frames[i]; ref var frame = ref frames[i];
if (frame.FrameType == RenderTreeFrameType.Component) if (frame.FrameType == RenderTreeFrameType.Component)

View File

@ -45,11 +45,11 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/// <summary> /// <summary>
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Element"/>, /// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Element"/>
/// gets the index of the final descendant frame in the tree. The value is /// gets the number of frames in the subtree for which this frame is the root.
/// zero if the frame has not yet been closed. /// The value is zero if the frame has not yet been closed.
/// </summary> /// </summary>
[FieldOffset(8)] public readonly int ElementDescendantsEndIndex; [FieldOffset(8)] public readonly int ElementSubtreeLength;
/// <summary> /// <summary>
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Element"/>, /// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Element"/>,
@ -88,11 +88,11 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
// -------------------------------------------------------------------------------- // --------------------------------------------------------------------------------
/// <summary> /// <summary>
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Component"/>, /// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Component"/>
/// gets the index of the final descendant frame in the tree. The value is /// gets the number of frames in the subtree for which this frame is the root.
/// zero if the frame has not yet been closed. /// The value is zero if the frame has not yet been closed.
/// </summary> /// </summary>
[FieldOffset(8)] public readonly int ComponentDescendantsEndIndex; [FieldOffset(8)] public readonly int ComponentSubtreeLength;
/// <summary> /// <summary>
/// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Component"/>, /// If the <see cref="FrameType"/> property equals <see cref="RenderTreeFrameType.Component"/>,
@ -112,26 +112,26 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
/// </summary> /// </summary>
[FieldOffset(24)] public readonly IComponent Component; [FieldOffset(24)] public readonly IComponent Component;
private RenderTreeFrame(int sequence, string elementName, int descendantsEndIndex) private RenderTreeFrame(int sequence, string elementName, int elementSubtreeLength)
: this() : this()
{ {
FrameType = RenderTreeFrameType.Element; FrameType = RenderTreeFrameType.Element;
Sequence = sequence; Sequence = sequence;
ElementName = elementName; ElementName = elementName;
ElementDescendantsEndIndex = descendantsEndIndex; ElementSubtreeLength = elementSubtreeLength;
} }
private RenderTreeFrame(int sequence, Type componentType, int descendantsEndIndex) private RenderTreeFrame(int sequence, Type componentType, int componentSubtreeLength)
: this() : this()
{ {
FrameType = RenderTreeFrameType.Component; FrameType = RenderTreeFrameType.Component;
Sequence = sequence; Sequence = sequence;
ComponentType = componentType; ComponentType = componentType;
ComponentDescendantsEndIndex = descendantsEndIndex; ComponentSubtreeLength = componentSubtreeLength;
} }
private RenderTreeFrame(int sequence, Type componentType, int descendantsEndIndex, int componentId, IComponent component) private RenderTreeFrame(int sequence, Type componentType, int subtreeLength, int componentId, IComponent component)
: this(sequence, componentType, descendantsEndIndex) : this(sequence, componentType, subtreeLength)
{ {
ComponentId = componentId; ComponentId = componentId;
Component = component; Component = component;
@ -155,7 +155,7 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
} }
internal static RenderTreeFrame Element(int sequence, string elementName) internal static RenderTreeFrame Element(int sequence, string elementName)
=> new RenderTreeFrame(sequence, elementName: elementName, descendantsEndIndex: 0); => new RenderTreeFrame(sequence, elementName: elementName, elementSubtreeLength: 0);
internal static RenderTreeFrame Text(int sequence, string textContent) internal static RenderTreeFrame Text(int sequence, string textContent)
=> new RenderTreeFrame(sequence, textContent: textContent); => new RenderTreeFrame(sequence, textContent: textContent);
@ -169,16 +169,16 @@ namespace Microsoft.AspNetCore.Blazor.RenderTree
internal static RenderTreeFrame ChildComponent<T>(int sequence) where T : IComponent internal static RenderTreeFrame ChildComponent<T>(int sequence) where T : IComponent
=> new RenderTreeFrame(sequence, typeof(T), 0); => new RenderTreeFrame(sequence, typeof(T), 0);
internal RenderTreeFrame WithElementDescendantsEndIndex(int descendantsEndIndex) internal RenderTreeFrame WithElementSubtreeLength(int elementSubtreeLength)
=> new RenderTreeFrame(Sequence, elementName: ElementName, descendantsEndIndex: descendantsEndIndex); => new RenderTreeFrame(Sequence, elementName: ElementName, elementSubtreeLength: elementSubtreeLength);
internal RenderTreeFrame WithComponentDescendantsEndIndex(int descendantsEndIndex) internal RenderTreeFrame WithComponentSubtreeLength(int componentSubtreeLength)
=> new RenderTreeFrame(Sequence, componentType: ComponentType, descendantsEndIndex: descendantsEndIndex); => new RenderTreeFrame(Sequence, componentType: ComponentType, componentSubtreeLength: componentSubtreeLength);
internal RenderTreeFrame WithAttributeSequence(int sequence) internal RenderTreeFrame WithAttributeSequence(int sequence)
=> new RenderTreeFrame(sequence, attributeName: AttributeName, attributeValue: AttributeValue); => new RenderTreeFrame(sequence, attributeName: AttributeName, attributeValue: AttributeValue);
internal RenderTreeFrame WithComponentInstance(int componentId, IComponent component) internal RenderTreeFrame WithComponentInstance(int componentId, IComponent component)
=> new RenderTreeFrame(Sequence, ComponentType, ComponentDescendantsEndIndex, componentId, component); => new RenderTreeFrame(Sequence, ComponentType, ComponentSubtreeLength, componentId, component);
} }
} }

View File

@ -157,7 +157,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "myelem", 1, 0), frame => AssertFrame.Element(frame, "myelem", 2, 0),
frame => AssertFrame.Text(frame, "Hello", 1)); frame => AssertFrame.Text(frame, "Hello", 1));
} }
@ -193,7 +193,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 2, 0), frame => AssertFrame.Element(frame, "elem", 3, 0),
frame => AssertFrame.Attribute(frame, "attrib-one", "Value 1", 1), frame => AssertFrame.Attribute(frame, "attrib-one", "Value 1", 1),
frame => AssertFrame.Attribute(frame, "a2", "v2", 2)); frame => AssertFrame.Attribute(frame, "a2", "v2", 2));
} }
@ -208,7 +208,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => AssertFrame.Attribute(frame, "attr", "My string", 1)); frame => AssertFrame.Attribute(frame, "attr", "My string", 1));
} }
@ -222,7 +222,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => AssertFrame.Attribute(frame, "attr", "123", 1)); frame => AssertFrame.Attribute(frame, "attr", "123", 1));
} }
@ -236,7 +236,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => AssertFrame.Attribute(frame, "attr", "Hello, WORLD with number 246!", 1)); frame => AssertFrame.Attribute(frame, "attr", "Hello, WORLD with number 246!", 1));
} }
@ -259,7 +259,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.False((bool)handlerWasCalledProperty.GetValue(component)); Assert.False((bool)handlerWasCalledProperty.GetValue(component));
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => frame =>
{ {
Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType); Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType);
@ -287,7 +287,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.False((bool)didInvokeCodeProperty.GetValue(component)); Assert.False((bool)didInvokeCodeProperty.GetValue(component));
Assert.Collection(frames, Assert.Collection(frames,
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => frame =>
{ {
Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType); Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType);
@ -336,7 +336,7 @@ namespace Microsoft.AspNetCore.Blazor.Build.Test
// Assert // Assert
Assert.False((bool)didInvokeCodeProperty.GetValue(component)); Assert.False((bool)didInvokeCodeProperty.GetValue(component));
Assert.Collection(GetRenderTree(component), Assert.Collection(GetRenderTree(component),
frame => AssertFrame.Element(frame, "elem", 1, 0), frame => AssertFrame.Element(frame, "elem", 2, 0),
frame => frame =>
{ {
Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType); Assert.Equal(RenderTreeFrameType.Attribute, frame.FrameType);

View File

@ -73,7 +73,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
} }
[Fact] [Fact]
public void UnclosedElementsHaveNoEndDescendantIndex() public void UnclosedElementsHaveNoSubtreeLength()
{ {
// Arrange // Arrange
var builder = new RenderTreeBuilder(new TestRenderer()); var builder = new RenderTreeBuilder(new TestRenderer());
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
} }
[Fact] [Fact]
public void ClosedEmptyElementsHaveSelfAsEndDescendantIndex() public void ClosedEmptyElementsHaveSubtreeLengthOne()
{ {
// Arrange // Arrange
var builder = new RenderTreeBuilder(new TestRenderer()); var builder = new RenderTreeBuilder(new TestRenderer());
@ -104,7 +104,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
} }
[Fact] [Fact]
public void ClosedElementsHaveCorrectEndDescendantIndex() public void ClosedElementsHaveCorrectSubtreeLength()
{ {
// Arrange // Arrange
var builder = new RenderTreeBuilder(new TestRenderer()); var builder = new RenderTreeBuilder(new TestRenderer());
@ -119,7 +119,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
// Assert // Assert
var frames = builder.GetFrames(); var frames = builder.GetFrames();
Assert.Equal(4, frames.Count); Assert.Equal(4, frames.Count);
AssertFrame.Element(frames.Array[0], "my element", 2); AssertFrame.Element(frames.Array[0], "my element", 3);
} }
[Fact] [Fact]
@ -152,13 +152,13 @@ namespace Microsoft.AspNetCore.Blazor.Test
frame => AssertFrame.Element(frame, "root", 10), frame => AssertFrame.Element(frame, "root", 10),
frame => AssertFrame.Text(frame, "root text 1"), frame => AssertFrame.Text(frame, "root text 1"),
frame => AssertFrame.Text(frame, "root text 2"), frame => AssertFrame.Text(frame, "root text 2"),
frame => AssertFrame.Element(frame, "child", 8), frame => AssertFrame.Element(frame, "child", 5),
frame => AssertFrame.Text(frame, "child text"), frame => AssertFrame.Text(frame, "child text"),
frame => AssertFrame.Element(frame, "grandchild", 8), frame => AssertFrame.Element(frame, "grandchild", 3),
frame => AssertFrame.Text(frame, "grandchild text 1"), frame => AssertFrame.Text(frame, "grandchild text 1"),
frame => AssertFrame.Text(frame, "grandchild text 2"), frame => AssertFrame.Text(frame, "grandchild text 2"),
frame => AssertFrame.Text(frame, "root text 3"), frame => AssertFrame.Text(frame, "root text 3"),
frame => AssertFrame.Element(frame, "child 2", 10), frame => AssertFrame.Element(frame, "child 2", 1),
frame => AssertFrame.Text(frame, "standalone text 2")); frame => AssertFrame.Text(frame, "standalone text 2"));
} }
@ -181,10 +181,10 @@ namespace Microsoft.AspNetCore.Blazor.Test
// Assert // Assert
Assert.Collection(builder.GetFrames(), Assert.Collection(builder.GetFrames(),
frame => AssertFrame.Element(frame, "myelement", 5), frame => AssertFrame.Element(frame, "myelement", 6),
frame => AssertFrame.Attribute(frame, "attribute1", "value 1"), frame => AssertFrame.Attribute(frame, "attribute1", "value 1"),
frame => AssertFrame.Attribute(frame, "attribute2", "123"), frame => AssertFrame.Attribute(frame, "attribute2", "123"),
frame => AssertFrame.Element(frame, "child", 5), frame => AssertFrame.Element(frame, "child", 3),
frame => AssertFrame.Attribute(frame, "childevent", eventHandler), frame => AssertFrame.Attribute(frame, "childevent", eventHandler),
frame => AssertFrame.Text(frame, "some text")); frame => AssertFrame.Text(frame, "some text"));
} }
@ -264,7 +264,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
// Assert // Assert
Assert.Collection(builder.GetFrames(), Assert.Collection(builder.GetFrames(),
frame => AssertFrame.Element(frame, "parent", 5), frame => AssertFrame.Element(frame, "parent", 6),
frame => AssertFrame.Component<TestComponent>(frame), frame => AssertFrame.Component<TestComponent>(frame),
frame => AssertFrame.Attribute(frame, "child1attribute1", "A"), frame => AssertFrame.Attribute(frame, "child1attribute1", "A"),
frame => AssertFrame.Attribute(frame, "child1attribute2", "B"), frame => AssertFrame.Attribute(frame, "child1attribute2", "B"),

View File

@ -313,7 +313,9 @@ namespace Microsoft.AspNetCore.Blazor.Test
{ {
// Arrange // Arrange
oldTree.OpenComponent<FakeComponent>(123); oldTree.OpenComponent<FakeComponent>(123);
oldTree.CloseComponent();
newTree.OpenComponent<FakeComponent2>(123); newTree.OpenComponent<FakeComponent2>(123);
newTree.CloseComponent();
// Act // Act
var renderBatch = GetRenderedBatch(); var renderBatch = GetRenderedBatch();

View File

@ -32,7 +32,7 @@ namespace Microsoft.AspNetCore.Blazor.Test
// Assert // Assert
Assert.Collection(renderer.Batches.Single().RenderTreesByComponentId[componentId], Assert.Collection(renderer.Batches.Single().RenderTreesByComponentId[componentId],
frame => AssertFrame.Element(frame, "my element", 1), frame => AssertFrame.Element(frame, "my element", 2),
frame => AssertFrame.Text(frame, "some text")); frame => AssertFrame.Text(frame, "some text"));
} }

View File

@ -22,15 +22,15 @@ namespace Microsoft.AspNetCore.Blazor.Test.Shared
{ {
Assert.Equal(RenderTreeFrameType.Text, frame.FrameType); Assert.Equal(RenderTreeFrameType.Text, frame.FrameType);
Assert.Equal(textContent, frame.TextContent); Assert.Equal(textContent, frame.TextContent);
Assert.Equal(0, frame.ElementDescendantsEndIndex); Assert.Equal(0, frame.ElementSubtreeLength);
AssertFrame.Sequence(frame, sequence); AssertFrame.Sequence(frame, sequence);
} }
public static void Element(RenderTreeFrame frame, string elementName, int descendantsEndIndex, int? sequence = null) public static void Element(RenderTreeFrame frame, string elementName, int subtreeLength, int? sequence = null)
{ {
Assert.Equal(RenderTreeFrameType.Element, frame.FrameType); Assert.Equal(RenderTreeFrameType.Element, frame.FrameType);
Assert.Equal(elementName, frame.ElementName); Assert.Equal(elementName, frame.ElementName);
Assert.Equal(descendantsEndIndex, frame.ElementDescendantsEndIndex); Assert.Equal(subtreeLength, frame.ElementSubtreeLength);
AssertFrame.Sequence(frame, sequence); AssertFrame.Sequence(frame, sequence);
} }