Node.getParent(): returns any parent inside an Optional
Root nodes will return an empty Optional.
This commit is contained in:
parent
37562941f4
commit
6c13cd2735
3 changed files with 33 additions and 31 deletions
|
@ -53,13 +53,10 @@ public interface Node<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the parent node.
|
* Fetch the parent node.
|
||||||
* <p>
|
|
||||||
* If the node is a root node, i.e. has no parent, then this will return
|
|
||||||
* null.
|
|
||||||
*
|
*
|
||||||
* @return the parent node
|
* @return an Optional contain the parent node, or empty if a root node
|
||||||
*/
|
*/
|
||||||
Node<T> getParent();
|
Optional<Node<T>> getParent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the current node a direct child of the parent.
|
* Make the current node a direct child of the parent.
|
||||||
|
|
|
@ -139,8 +139,8 @@ public class NodeItem<T> implements Node<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node<T> getParent() {
|
public Optional<Node<T>> getParent() {
|
||||||
return parent;
|
return Optional.ofNullable(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -170,7 +170,12 @@ public class NodeItem<T> implements Node<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
children.add(child);
|
children.add(child);
|
||||||
if (child.getParent() == null || !child.getParent().equals(this)) {
|
// update the child's parent if they don't have one or it is not this
|
||||||
|
Optional<Node<T>> childParent = child.getParent();
|
||||||
|
boolean isOrphan = !childParent.isPresent();
|
||||||
|
boolean hasDifferentParent = !isOrphan && !childParent.get()
|
||||||
|
.equals(this);
|
||||||
|
if (isOrphan || hasDifferentParent) {
|
||||||
child.setParent(this);
|
child.setParent(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class NodeItemTest {
|
||||||
node = new NodeItem<>("data");
|
node = new NodeItem<>("data");
|
||||||
//then
|
//then
|
||||||
assertThat(node.getParent()).as(
|
assertThat(node.getParent()).as(
|
||||||
"node created without a parent has null as parent").isNull();
|
"node created without a parent has no parent").isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -94,7 +94,7 @@ public class NodeItemTest {
|
||||||
//then
|
//then
|
||||||
assertThat(node.getParent()).as(
|
assertThat(node.getParent()).as(
|
||||||
"node created with a parent can return the parent")
|
"node created with a parent can return the parent")
|
||||||
.isSameAs(parent);
|
.contains(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,7 +142,7 @@ public class NodeItemTest {
|
||||||
//then
|
//then
|
||||||
assertThat(node.getParent()).as(
|
assertThat(node.getParent()).as(
|
||||||
"when a node is assigned a new parent that parent can be "
|
"when a node is assigned a new parent that parent can be "
|
||||||
+ "returned").isSameAs(parent);
|
+ "returned").contains(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -187,7 +187,7 @@ public class NodeItemTest {
|
||||||
//then
|
//then
|
||||||
assertThat(child.getParent()).as(
|
assertThat(child.getParent()).as(
|
||||||
"when a node is assigned a new parent, the old parent is "
|
"when a node is assigned a new parent, the old parent is "
|
||||||
+ "replaced").isSameAs(newParent);
|
+ "replaced").contains(newParent);
|
||||||
assertThat(node.findChild("child").isPresent()).as(
|
assertThat(node.findChild("child").isPresent()).as(
|
||||||
"when a node is assigned a new parent, the old parent no "
|
"when a node is assigned a new parent, the old parent no "
|
||||||
+ "longer has the node among it's children").isFalse();
|
+ "longer has the node among it's children").isFalse();
|
||||||
|
@ -209,7 +209,7 @@ public class NodeItemTest {
|
||||||
assertThat(child.getParent()).as(
|
assertThat(child.getParent()).as(
|
||||||
"when a node with an existing parent is added as a child "
|
"when a node with an existing parent is added as a child "
|
||||||
+ "to another node, then the old parent is replaced")
|
+ "to another node, then the old parent is replaced")
|
||||||
.isSameAs(newParent);
|
.contains(newParent);
|
||||||
assertThat(node.findChild("child").isPresent()).as(
|
assertThat(node.findChild("child").isPresent()).as(
|
||||||
"when a node with an existing parent is added as a child to "
|
"when a node with an existing parent is added as a child to "
|
||||||
+ "another node, then the old parent no longer has "
|
+ "another node, then the old parent no longer has "
|
||||||
|
@ -309,14 +309,14 @@ public class NodeItemTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldSetParentOnChildWhenAddedAsChild() {
|
public void shouldSetParentOnChildWhenAddedAsChild() {
|
||||||
//given
|
//given
|
||||||
val child = new NodeItem<String>("child");
|
|
||||||
node = new NodeItem<>("subject");
|
node = new NodeItem<>("subject");
|
||||||
|
val child = new NodeItem<String>("child");
|
||||||
//when
|
//when
|
||||||
node.addChild(child);
|
node.addChild(child);
|
||||||
//then
|
//then
|
||||||
assertThat(child.getParent()).as(
|
assertThat(child.getParent()).as(
|
||||||
"when a node is added as a child, the child has the node as "
|
"when a node is added as a child, the child has the node as "
|
||||||
+ "its parent").isSameAs(node);
|
+ "its parent").contains(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -411,7 +411,7 @@ public class NodeItemTest {
|
||||||
val alpha = alphaOptional.get();
|
val alpha = alphaOptional.get();
|
||||||
assertThat(alpha.getParent()).as(
|
assertThat(alpha.getParent()).as(
|
||||||
"when creating a descendant line, the first element has "
|
"when creating a descendant line, the first element has "
|
||||||
+ "the current node as its parent").isSameAs(node);
|
+ "the current node as its parent").contains(node);
|
||||||
val betaOptional = alpha.findChild(betaData);
|
val betaOptional = alpha.findChild(betaData);
|
||||||
assertThat(betaOptional.isPresent()).as(
|
assertThat(betaOptional.isPresent()).as(
|
||||||
"when creating a descendant line, the second element is "
|
"when creating a descendant line, the second element is "
|
||||||
|
@ -421,7 +421,7 @@ public class NodeItemTest {
|
||||||
assertThat(beta.getParent()).as(
|
assertThat(beta.getParent()).as(
|
||||||
"when creating a descendant line, the second element "
|
"when creating a descendant line, the second element "
|
||||||
+ "has the first as its parent")
|
+ "has the first as its parent")
|
||||||
.isSameAs(alpha);
|
.contains(alpha);
|
||||||
val gammaOptional = beta.findChild(gammaData);
|
val gammaOptional = beta.findChild(gammaData);
|
||||||
assertThat(gammaOptional.isPresent()).as(
|
assertThat(gammaOptional.isPresent()).as(
|
||||||
"when creating a descendant line, the third element "
|
"when creating a descendant line, the third element "
|
||||||
|
@ -431,7 +431,7 @@ public class NodeItemTest {
|
||||||
assertThat(gamma.getParent()).as(
|
assertThat(gamma.getParent()).as(
|
||||||
"when creating a descendant line, the third "
|
"when creating a descendant line, the third "
|
||||||
+ "element has the second as its parent")
|
+ "element has the second as its parent")
|
||||||
.isSameAs(beta);
|
.contains(beta);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -561,7 +561,7 @@ public class NodeItemTest {
|
||||||
//then
|
//then
|
||||||
assertThat(child.getParent()).as(
|
assertThat(child.getParent()).as(
|
||||||
"when creating a child node, the child has the current node "
|
"when creating a child node, the child has the current node "
|
||||||
+ "as its parent").isSameAs(node);
|
+ "as its parent").contains(node);
|
||||||
val foundChild = node.findChild(childData);
|
val foundChild = node.findChild(childData);
|
||||||
assertThat(foundChild.isPresent()).as(
|
assertThat(foundChild.isPresent()).as(
|
||||||
"when creating a child node, the child can be found by its "
|
"when creating a child node, the child can be found by its "
|
||||||
|
@ -698,14 +698,14 @@ public class NodeItemTest {
|
||||||
//when
|
//when
|
||||||
node.insertInPath(four, "one", "two", "three");
|
node.insertInPath(four, "one", "two", "three");
|
||||||
//then
|
//then
|
||||||
val three = four.getParent();
|
val three = four.getParent().get();
|
||||||
assertThat(four.getParent()).as("add node to a tree").isNotNull();
|
assertThat(four.getParent()).as("add node to a tree").isNotNull();
|
||||||
assertThat(three.getName()).isEqualTo("three");
|
assertThat(three.getName()).isEqualTo("three");
|
||||||
val two = three.getParent();
|
val two = three.getParent().get();
|
||||||
assertThat(two.getName()).isEqualTo("two");
|
assertThat(two.getName()).isEqualTo("two");
|
||||||
val one = two.getParent();
|
val one = two.getParent().get();
|
||||||
assertThat(one.getName()).isEqualTo("one");
|
assertThat(one.getName()).isEqualTo("one");
|
||||||
assertThat(one.getParent()).isSameAs(node);
|
assertThat(one.getParent().get()).isSameAs(node);
|
||||||
assertThat(node.getChildByName("one")
|
assertThat(node.getChildByName("one")
|
||||||
.getChildByName("two")
|
.getChildByName("two")
|
||||||
.getChildByName("three")
|
.getChildByName("three")
|
||||||
|
@ -764,7 +764,7 @@ public class NodeItemTest {
|
||||||
//when
|
//when
|
||||||
child.removeParent();
|
child.removeParent();
|
||||||
//then
|
//then
|
||||||
assertThat(child.getParent()).isNull();
|
assertThat(child.getParent()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -805,7 +805,7 @@ public class NodeItemTest {
|
||||||
node.addChild(child);
|
node.addChild(child);
|
||||||
child.addChild(target);
|
child.addChild(target);
|
||||||
final NodeItem<String> addMe = new NodeItem<>("I'm new", "target");
|
final NodeItem<String> addMe = new NodeItem<>("I'm new", "target");
|
||||||
assertThat(addMe.getParent()).isNull();
|
assertThat(addMe.getParent()).isEmpty();
|
||||||
assertThat(child.getChildByName("target").isEmpty()).as(
|
assertThat(child.getChildByName("target").isEmpty()).as(
|
||||||
"target starts empty").isTrue();
|
"target starts empty").isTrue();
|
||||||
//when
|
//when
|
||||||
|
@ -920,7 +920,7 @@ public class NodeItemTest {
|
||||||
Node<String> child = node.createChild("child data", "child name");
|
Node<String> child = node.createChild("child data", "child name");
|
||||||
//then
|
//then
|
||||||
assertThat(child.getName()).isEqualTo("child name");
|
assertThat(child.getName()).isEqualTo("child name");
|
||||||
assertThat(child.getParent()).isSameAs(node);
|
assertThat(child.getParent()).contains(node);
|
||||||
assertThat(node.getChildren()).containsExactly(child);
|
assertThat(node.getChildren()).containsExactly(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -953,7 +953,7 @@ public class NodeItemTest {
|
||||||
//when
|
//when
|
||||||
NodeItem<String> child = new NodeItem<>(null, node);
|
NodeItem<String> child = new NodeItem<>(null, node);
|
||||||
//then
|
//then
|
||||||
assertThat(child.getParent()).isSameAs(node);
|
assertThat(child.getParent()).contains(node);
|
||||||
assertThat(node.getChildren()).containsExactly(child);
|
assertThat(node.getChildren()).containsExactly(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1024,11 +1024,11 @@ public class NodeItemTest {
|
||||||
public void canUseNameSupplierToBuildFullPath() {
|
public void canUseNameSupplierToBuildFullPath() {
|
||||||
//given
|
//given
|
||||||
final Function<Node<String>, String> pathNameSupplier = node -> {
|
final Function<Node<String>, String> pathNameSupplier = node -> {
|
||||||
Node<String> parent = node.getParent();
|
Optional<Node<String>> parent = node.getParent();
|
||||||
if (parent == null) {
|
if (parent.isPresent()) {
|
||||||
return "";
|
return parent.get().getName() + "/" + node.getData().get();
|
||||||
}
|
}
|
||||||
return parent.getName() + "/" + node.getData().get();
|
return "";
|
||||||
};
|
};
|
||||||
node = new NodeItem<>(null, pathNameSupplier);
|
node = new NodeItem<>(null, pathNameSupplier);
|
||||||
val child = new NodeItem<String>("child", node);
|
val child = new NodeItem<String>("child", node);
|
||||||
|
|
Loading…
Reference in a new issue