From 1391d6e8172612e8a03e8219695e76c1a04580a3 Mon Sep 17 00:00:00 2001 From: Andrej Rypo Date: Sun, 4 Feb 2024 20:47:28 +0100 Subject: [PATCH] Tree::link disciplined minor edge-case issue corrected --- src/Tree.php | 8 +++++-- tests/tree.phpt | 56 ++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/src/Tree.php b/src/Tree.php index 9ab4d62..8f36d96 100644 --- a/src/Tree.php +++ b/src/Tree.php @@ -162,8 +162,12 @@ private static function adoptChild( string|int|null $key = null ): void { $existing = $parent->childKey($child); - if (null !== $existing && $parent->child($existing) === $child) { - // Already linked. + if ( + null !== $existing && + $parent->child($existing) === $child && + (null === $key || $existing === $key) + ) { + // Already linked (with the same key or key not important). return; } $parent->addChild($child, $key); diff --git a/tests/tree.phpt b/tests/tree.phpt index 9649847..4c05ea3 100644 --- a/tests/tree.phpt +++ b/tests/tree.phpt @@ -60,6 +60,60 @@ require_once __DIR__ . '/setup.php'; })(); (function () { - // + $node = new Node(null, parent: $parent = new Node(null)); + + Assert::same($parent, $node->parent()); + Assert::same([], $parent->children()); + + Tree::link($node, $parent); + Assert::same($parent, $node->parent()); + Assert::same([$node], $parent->children()); +})(); + +(function () { + $parent = new Node(null, children: [ + $node = new Node(null), + ]); + + Assert::same(null, $node->parent()); + Assert::same([$node], $parent->children()); + + Tree::link($node, $parent); + Assert::same($parent, $node->parent()); + Assert::same([$node], $parent->children()); +})(); + +(function () { + $proxy = new NodeBuilder(fn(mixed $data) => new Node($data)); + + $parent = $proxy->node(null, [ + 'original' => $node = new Node(null), + ]); + + Assert::same($parent, $node->parent()); + Assert::same(['original' => $node], $parent->children()); + + Tree::link($node, $parent, 'new-key'); + Assert::same($parent, $node->parent()); + Assert::same(['new-key' => $node], $parent->children()); +})(); + +(function () { + $proxy = new NodeBuilder(fn(mixed $data) => new Node($data)); + + $parent = $proxy->node(null, [ + 'original' => $node = new Node(null), + ]); + + Assert::same($parent, $node->parent()); + Assert::same(['original' => $node], $parent->children()); + + Tree::link($node, $parent, 'original'); + Assert::same($parent, $node->parent()); + Assert::same(['original' => $node], $parent->children()); + + Tree::link($node, $parent); + Assert::same($parent, $node->parent()); + Assert::same(['original' => $node], $parent->children()); })();