fix(dock): fix InsertChild move semantics and improve test quality

This commit is contained in:
2026-03-28 14:57:52 +09:00
parent e69e071ce2
commit b3d753fd08
3 changed files with 22 additions and 10 deletions

View File

@@ -74,7 +74,17 @@ public partial class DockGroupNode : DockNode
int oldIndex = _children.IndexOf(node); int oldIndex = _children.IndexOf(node);
if (oldIndex == index) return; if (oldIndex == index) return;
_children.Move(oldIndex, index); // ObservableCollection.Move(oldIndex, newIndex) requires newIndex < Count.
// If index is Count, we move it to the last position (Count - 1).
int targetIndex = index;
if (targetIndex >= _children.Count)
{
targetIndex = _children.Count - 1;
}
if (oldIndex == targetIndex) return;
_children.Move(oldIndex, targetIndex);
return; return;
} }

View File

@@ -414,7 +414,7 @@ public sealed partial class DockLayout : Control
/// Applies the tree mutation for a drop operation. /// Applies the tree mutation for a drop operation.
/// </summary> /// </summary>
/// <returns>True if the mutation was applied; otherwise, false.</returns> /// <returns>True if the mutation was applied; otherwise, false.</returns>
private bool TryApplyDropMutation(DockPanelNode targetNode, DockPanelNode sourceNode, object item, DockPosition position) internal bool TryApplyDropMutation(DockPanelNode targetNode, DockPanelNode sourceNode, object item, DockPosition position)
{ {
if (position == DockPosition.Center) if (position == DockPosition.Center)
{ {

View File

@@ -19,11 +19,12 @@ public class DockingMutationTest
root.AddChild(panel2); root.AddChild(panel2);
// Simulate Center Drop: panel1 -> panel2 // Simulate Center Drop: panel1 -> panel2
panel1.Items.Remove(item); bool removed = panel1.Items.Remove(item);
Assert.IsTrue(removed);
panel2.Items.Add(item); panel2.Items.Add(item);
Assert.AreEqual(0, panel1.Items.Count); Assert.IsEmpty(panel1.Items);
Assert.AreEqual(1, panel2.Items.Count); Assert.HasCount(1, panel2.Items);
Assert.AreEqual(item, panel2.Items[0]); Assert.AreEqual(item, panel2.Items[0]);
} }
@@ -39,7 +40,8 @@ public class DockingMutationTest
// Simulate Vertical Split Drop (Bottom) on panel1 // Simulate Vertical Split Drop (Bottom) on panel1
// 1. Remove from source // 1. Remove from source
panel1.Items.Remove(item); bool removed = panel1.Items.Remove(item);
Assert.IsTrue(removed);
// 2. Different orientation (Vertical), replace panel1 with new group // 2. Different orientation (Vertical), replace panel1 with new group
root.RemoveChild(panel1); root.RemoveChild(panel1);
@@ -51,9 +53,9 @@ public class DockingMutationTest
newGroup.AddChild(newNode); // New split newGroup.AddChild(newNode); // New split
root.AddChild(newGroup); root.AddChild(newGroup);
Assert.AreEqual(1, root.Children.Count); Assert.HasCount(1, root.Children);
Assert.AreEqual(newGroup, root.Children[0]); Assert.AreEqual(newGroup, root.Children[0]);
Assert.AreEqual(2, newGroup.Children.Count); Assert.HasCount(2, newGroup.Children);
Assert.AreEqual(panel1, newGroup.Children[0]); Assert.AreEqual(panel1, newGroup.Children[0]);
Assert.AreEqual(newNode, newGroup.Children[1]); Assert.AreEqual(newNode, newGroup.Children[1]);
Assert.AreEqual(item, newNode.Items[0]); Assert.AreEqual(item, newNode.Items[0]);
@@ -82,7 +84,7 @@ public class DockingMutationTest
root.RemoveChild(group1); root.RemoveChild(group1);
} }
Assert.AreEqual(0, root.Children.Count); Assert.IsEmpty(root.Children);
Assert.IsNull(group1.Parent); Assert.IsNull(group1.Parent);
Assert.IsNull(panel1.Parent); Assert.IsNull(panel1.Parent);
} }
@@ -114,7 +116,7 @@ public class DockingMutationTest
parent.InsertChild(index, onlyChild); parent.InsertChild(index, onlyChild);
} }
Assert.AreEqual(1, root.Children.Count); Assert.HasCount(1, root.Children);
Assert.AreEqual(panel1, root.Children[0]); Assert.AreEqual(panel1, root.Children[0]);
Assert.AreEqual(root, panel1.Parent); Assert.AreEqual(root, panel1.Parent);
} }