From 05223e56964c437c0ea29603e70a9fcb492679ac Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 10:23:44 +1000 Subject: [PATCH 1/6] Failing test --- tests/Functional/DbalNestedSetTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index f402b753..3e1d65d3 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -461,6 +461,13 @@ public function testValidateTableInvalidFirstChars() { $this->nestedSet = new DbalNestedSet($this->connection, "1abc"); } + /** + * Test get tree works. + */ + public function testGetTree() { + $this->assertCount(11, $this->nestedSet->getTree()); + } + /** * Loads the test data. */ From 8c13b99187ddf9d44512e12020e29683d67c0571 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 10:24:18 +1000 Subject: [PATCH 2/6] Fix getTree --- src/Storage/DbalNestedSet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Storage/DbalNestedSet.php b/src/Storage/DbalNestedSet.php index 3bb93bd0..76186930 100644 --- a/src/Storage/DbalNestedSet.php +++ b/src/Storage/DbalNestedSet.php @@ -211,7 +211,7 @@ public function getTree() { $tree = []; $stmt = $this->connection->executeQuery('SELECT id, revision_id, left_pos, right_pos, depth FROM ' . $this->tableName . ' ORDER BY left_pos'); while ($row = $stmt->fetch()) { - $tree[] = new Node($row['id'], $row['revision_id'], $row['left_pos'], $row['right_pos'], $row['depth']); + $tree[] = new Node(new NodeKey($row['id'], $row['revision_id']), $row['left_pos'], $row['right_pos'], $row['depth']); } return $tree; } From 602f0cdbc45f7dd192eb54936618921a679b1ce6 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 10:55:38 +1000 Subject: [PATCH 3/6] Test for moving to new parentnode --- tests/Functional/DbalNestedSetTest.php | 40 ++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index 3e1d65d3..dfb8920b 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -346,6 +346,46 @@ public function testMoveSubTreeBelow() { } + /** + * Tests moving a sub-tree under a brand new parent node. + */ + public function testMoveSubTreeBelowEndParentNode() { + + $parent = $this->nestedSet->getNode(new NodeKey(1, 1)); + $nodeKey = new NodeKey(7, 1); + $node = $this->nestedSet->getNode($nodeKey); + + $this->printTree($this->nestedSet->getTree()); + $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); + $this->printTree($this->nestedSet->getTree()); + $this->nestedSet->moveSubTreeBelow($newRoot, $node); + $this->printTree($this->nestedSet->getTree()); + + // Check node is in new position. + $node = $this->nestedSet->getNode($nodeKey); + $this->assertEquals(18, $node->getLeft()); + $this->assertEquals(23, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + // Check children are in new position. + $node = $this->nestedSet->getNode(new NodeKey(10, 1)); + $this->assertEquals(19, $node->getLeft()); + $this->assertEquals(20, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + $node = $this->nestedSet->getNode(new NodeKey(11, 1)); + $this->assertEquals(21, $node->getLeft()); + $this->assertEquals(22, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + // Check old parent is updated. + $node = $this->nestedSet->getNode(new NodeKey(3, 1)); + $this->assertEquals(10, $node->getLeft()); + $this->assertEquals(15, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + } + /** * Tests moving a sub-tree to the root. */ From 8dc4d3ac9e6e7c83415abb1ef1366e73c743bfc1 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 11:02:10 +1000 Subject: [PATCH 4/6] Fix for move below with no existing siblings --- src/Storage/DbalNestedSet.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/Storage/DbalNestedSet.php b/src/Storage/DbalNestedSet.php index 76186930..15840ead 100644 --- a/src/Storage/DbalNestedSet.php +++ b/src/Storage/DbalNestedSet.php @@ -349,7 +349,13 @@ protected function moveSubTreeToPosition($newLeftPosition, Node $node) { // Calculate depth difference. $newNode = $this->getNodeAtPosition($newLeftPosition); - $depthDiff = $newNode->getDepth() - $node->getDepth(); + if (!$newNode) { + // No other children at this position, new depth = 1. + $depthDiff = 1 - $node->getDepth(); + } + else { + $depthDiff = $newNode->getDepth() - $node->getDepth(); + } // Backwards movement must account for new space. if ($distance < 0) { From 694abf75d53023a137921b1b3b78104b81dae753 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 11:07:52 +1000 Subject: [PATCH 5/6] Failing test for hard-coding 1 --- tests/Functional/DbalNestedSetTest.php | 44 ++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index dfb8920b..8ffe42dd 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -355,11 +355,8 @@ public function testMoveSubTreeBelowEndParentNode() { $nodeKey = new NodeKey(7, 1); $node = $this->nestedSet->getNode($nodeKey); - $this->printTree($this->nestedSet->getTree()); $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); - $this->printTree($this->nestedSet->getTree()); $this->nestedSet->moveSubTreeBelow($newRoot, $node); - $this->printTree($this->nestedSet->getTree()); // Check node is in new position. $node = $this->nestedSet->getNode($nodeKey); @@ -386,6 +383,47 @@ public function testMoveSubTreeBelowEndParentNode() { } + /** + * Tests moving a sub-tree under a brand new child node. + */ + public function testMoveSubTreeBelowEndChildNode() { + + $parent = $this->nestedSet->getNode(new NodeKey(1, 1)); + $nodeKey = new NodeKey(7, 1); + $node = $this->nestedSet->getNode($nodeKey); + + $this->printTree($this->nestedSet->getTree()); + $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); + $newChild = $this->nestedSet->addNodeBelow($newRoot, new NodeKey(13, 1)); + $this->printTree($this->nestedSet->getTree()); + $this->nestedSet->moveSubTreeBelow($newChild, $node); + $this->printTree($this->nestedSet->getTree()); + + // Check node is in new position. + $node = $this->nestedSet->getNode($nodeKey); + $this->assertEquals(19, $node->getLeft()); + $this->assertEquals(24, $node->getRight()); + $this->assertEquals(2, $node->getDepth()); + + // Check children are in new position. + $node = $this->nestedSet->getNode(new NodeKey(10, 1)); + $this->assertEquals(20, $node->getLeft()); + $this->assertEquals(21, $node->getRight()); + $this->assertEquals(3, $node->getDepth()); + + $node = $this->nestedSet->getNode(new NodeKey(11, 1)); + $this->assertEquals(22, $node->getLeft()); + $this->assertEquals(23, $node->getRight()); + $this->assertEquals(3, $node->getDepth()); + + // Check old parent is updated. + $node = $this->nestedSet->getNode(new NodeKey(3, 1)); + $this->assertEquals(10, $node->getLeft()); + $this->assertEquals(15, $node->getRight()); + $this->assertEquals(1, $node->getDepth()); + + } + /** * Tests moving a sub-tree to the root. */ From c98f146ff00bf3d8749db33e72116425f9742bc2 Mon Sep 17 00:00:00 2001 From: Lee Rowlands Date: Thu, 9 Feb 2017 11:11:08 +1000 Subject: [PATCH 6/6] Calculate the depth before calling --- src/Storage/DbalNestedSet.php | 19 +++++++------------ tests/Functional/DbalNestedSetTest.php | 3 --- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/Storage/DbalNestedSet.php b/src/Storage/DbalNestedSet.php index 15840ead..ab424ee9 100644 --- a/src/Storage/DbalNestedSet.php +++ b/src/Storage/DbalNestedSet.php @@ -308,7 +308,7 @@ public function moveSubTreeToRoot(Node $node) { */ public function moveSubTreeBelow(Node $target, Node $node) { $newLeftPosition = $target->getLeft() + 1; - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth() + 1); } /** @@ -316,7 +316,7 @@ public function moveSubTreeBelow(Node $target, Node $node) { */ public function moveSubTreeBefore(Node $target, Node $node) { $newLeftPosition = $target->getLeft(); - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth()); } /** @@ -324,7 +324,7 @@ public function moveSubTreeBefore(Node $target, Node $node) { */ public function moveSubTreeAfter(Node $target, Node $node) { $newLeftPosition = $target->getRight() + 1; - $this->moveSubTreeToPosition($newLeftPosition, $node); + $this->moveSubTreeToPosition($newLeftPosition, $node, $target->getDepth()); } /** @@ -334,11 +334,13 @@ public function moveSubTreeAfter(Node $target, Node $node) { * The new left position. * @param \PNX\NestedSet\Node $node * The node to move. + * @param int $newDepth + * Depth of new position. * * @throws \Exception * If a transaction error occurs. */ - protected function moveSubTreeToPosition($newLeftPosition, Node $node) { + protected function moveSubTreeToPosition($newLeftPosition, Node $node, $newDepth) { try { // Calculate position adjustment variables. $width = $node->getRight() - $node->getLeft() + 1; @@ -348,14 +350,7 @@ protected function moveSubTreeToPosition($newLeftPosition, Node $node) { $this->connection->beginTransaction(); // Calculate depth difference. - $newNode = $this->getNodeAtPosition($newLeftPosition); - if (!$newNode) { - // No other children at this position, new depth = 1. - $depthDiff = 1 - $node->getDepth(); - } - else { - $depthDiff = $newNode->getDepth() - $node->getDepth(); - } + $depthDiff = $newDepth - $node->getDepth(); // Backwards movement must account for new space. if ($distance < 0) { diff --git a/tests/Functional/DbalNestedSetTest.php b/tests/Functional/DbalNestedSetTest.php index 8ffe42dd..3cd67e00 100644 --- a/tests/Functional/DbalNestedSetTest.php +++ b/tests/Functional/DbalNestedSetTest.php @@ -392,12 +392,9 @@ public function testMoveSubTreeBelowEndChildNode() { $nodeKey = new NodeKey(7, 1); $node = $this->nestedSet->getNode($nodeKey); - $this->printTree($this->nestedSet->getTree()); $newRoot = $this->nestedSet->addRootNode(new NodeKey(12, 1)); $newChild = $this->nestedSet->addNodeBelow($newRoot, new NodeKey(13, 1)); - $this->printTree($this->nestedSet->getTree()); $this->nestedSet->moveSubTreeBelow($newChild, $node); - $this->printTree($this->nestedSet->getTree()); // Check node is in new position. $node = $this->nestedSet->getNode($nodeKey);