Skip to content

Commit 94f0b5c

Browse files
committed
test the new option
1 parent 9ccf1f2 commit 94f0b5c

File tree

2 files changed

+44
-4
lines changed

2 files changed

+44
-4
lines changed

src/Tree.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public static function link(
3232
MovableNodeContract $node,
3333
MovableNodeContract $parent,
3434
string|int|null $key = null,
35-
bool $preventDuplicateLinking = true,
35+
bool $handleDuplicateLinking = true,
3636
): ?MovableNodeContract {
3737
$currentParent = $node->parent();
3838

@@ -48,7 +48,7 @@ public static function link(
4848
}
4949

5050
// Create the parent-to-child link.
51-
self::adoptChild($parent, $node, $key, $preventDuplicateLinking);
51+
self::adoptChild($parent, $node, $key, $handleDuplicateLinking);
5252

5353
// If a parent was unlinked during the process, return it.
5454
return $originalParent ?? null;
@@ -165,12 +165,12 @@ private static function adoptChild(
165165
MovableNodeContract $parent,
166166
MovableNodeContract $child,
167167
string|int|null $key,
168-
bool $preventDuplicateLinking,
168+
bool $handleDuplicateLinking,
169169
): void {
170170
// Note:
171171
// The duplicate adding prevention is very slow for nodes with many siblings due to the child node lookup
172172
// (done by the `childKey` method), if not optimized internally.
173-
$existing = $preventDuplicateLinking ? $parent->childKey($child) : null;
173+
$existing = $handleDuplicateLinking ? $parent->childKey($child) : null;
174174
if (
175175
null !== $existing &&
176176
$parent->child($existing) === $child &&

tests/tree.phpt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ declare(strict_types=1);
44

55
namespace Dakujem\Test;
66

7+
use Dakujem\Oliva\Exceptions\ChildKeyCollision;
78
use Dakujem\Oliva\Exceptions\NodeNotMovable;
89
use Dakujem\Oliva\Node;
910
use Dakujem\Oliva\Simple\NodeBuilder;
@@ -187,3 +188,42 @@ require_once __DIR__ . '/setup.php';
187188
Assert::same(['two' => $node2, 'three' => $node1], $parent->children());
188189
})();
189190

191+
192+
(function () {
193+
//
194+
// Duplicate linking of the same node without duplicate handling does not prevent adding the same node multiple times.
195+
//
196+
197+
$node = new Node(null);
198+
$parent = new Node(null);
199+
Tree::link($node, $parent); // default index `0`
200+
201+
// this will add the same node duplicate under `1`,
202+
// behaves like an array push
203+
Tree::link($node, $parent, handleDuplicateLinking: false);
204+
Assert::same([0 => $node, 1 => $node], $parent->children());
205+
// this will add the same node yet again under `foo`
206+
Tree::link($node, $parent, 'foo', handleDuplicateLinking: false);
207+
Assert::same([0 => $node, 1 => $node, 'foo' => $node], $parent->children());
208+
209+
$node1 = new Node(null);
210+
$node2 = new Node(null);
211+
$children = ['one' => $node1, 'two' => $node2];
212+
$parent = new Node(null, children: $children);
213+
Assert::same($children, $parent->children()); // sanity check
214+
215+
// Attempting to add the same node under an existing (albeit same) key without duplicate node handling mechanism
216+
// results in a ChildKeyCollision exception.
217+
Assert::throws(function () use ($parent, $node1) {
218+
Tree::link($node1, $parent, 'one', handleDuplicateLinking: false);
219+
}, ChildKeyCollision::class);
220+
Assert::throws(function () use ($parent, $node1) {
221+
Tree::link($node1, $parent, 'two', handleDuplicateLinking: false);
222+
}, ChildKeyCollision::class);
223+
224+
// Without the duplicate node handling mechanism, this call will allow adding the node as a duplicate child,
225+
// possibly causing issues in the tree structure.
226+
Tree::link($node1, $parent, 'three', handleDuplicateLinking: false);
227+
Assert::same(['one' => $node1, 'two' => $node2, 'three' => $node1], $parent->children());
228+
})();
229+

0 commit comments

Comments
 (0)