Clean up Node interface (#60)
* NoteItem Remove @NonNull from private method parameters * When creating node with null children treat as no children * NodeItem use Lombok Getter/Setter * Extract NodeTreeDraw * Remove getData() * Remove getChild() * Remove getParent() * Remove getChildByName() * Merge NodeTreeDraw into Nodes * Remove methodcound suppression * [changelog] Updated
This commit is contained in:
parent
04e0e83748
commit
82f0c25b1d
9 changed files with 207 additions and 357 deletions
|
@ -9,16 +9,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
|
|
||||||
** Added
|
** Added
|
||||||
|
|
||||||
- Add kemitix-maven-tiles
|
- Add kemitix-maven-tiles 2.4.1
|
||||||
|
|
||||||
** Changed
|
** Changed
|
||||||
|
|
||||||
- Replace Jenkins with Github Actions (#57)
|
- Replace Jenkins with Github Actions (#57)
|
||||||
- [checkstyle] suppress npath complexity issues
|
- [checkstyle] suppress npath complexity issues
|
||||||
- [coverage] lower requirements
|
- [coverage] lower requirements
|
||||||
|
- Clean up changelog and readme, and remove external build dependencies (#38)
|
||||||
|
- Pinned pitest-junit5-plugin at 0.9 (#59)
|
||||||
|
- Moved: Node.drawTree to Nodes (#60)
|
||||||
|
|
||||||
|
** Removed
|
||||||
|
|
||||||
|
- Removed from Node: getChildByName, getParent, getChild, getData (#60
|
||||||
|
|
||||||
** Dependencies
|
** Dependencies
|
||||||
|
|
||||||
|
- Bump kemitix-checkstyle-ruleset from 4.0.1 to 5.4.0 (#59)
|
||||||
|
- Bump kemitix-parent from 5.2.0 to 5.3.0 (#56)
|
||||||
|
- Bump lombok from 1.18.10 to 1.18.12 (#55)
|
||||||
|
- Bump assertj-core from 3.13.2 to 3.15.0 (#54)
|
||||||
|
- Bump junit from 4.12 to 4.13 (#53)
|
||||||
|
- Bump tiles-maven-plugin from 2.15 to 2.16 (#52)
|
||||||
- Bump hamcrest-core from 2.1 to 2.2 (#50)
|
- Bump hamcrest-core from 2.1 to 2.2 (#50)
|
||||||
- Bump lombok from 1.18.8 to 1.18.10 (#49)
|
- Bump lombok from 1.18.8 to 1.18.10 (#49)
|
||||||
- Bump assertj-core from 3.12.2 to 3.13.2 (#48)
|
- Bump assertj-core from 3.12.2 to 3.13.2 (#48)
|
||||||
|
@ -29,7 +42,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- Bump lombok from 1.18.4 to 1.18.6 (#41)
|
- Bump lombok from 1.18.4 to 1.18.6 (#41)
|
||||||
- Bump tiles-maven-plugin from 2.12 to 2.13 (#40)
|
- Bump tiles-maven-plugin from 2.12 to 2.13 (#40)
|
||||||
- Bump hamcrest-core from 1.3 to 2.1 (#37)
|
- Bump hamcrest-core from 1.3 to 2.1 (#37)
|
||||||
- Clean up changelog and readme, and remove external build dependencies (#38)
|
|
||||||
|
|
||||||
* [0.7.0] - 2017-02-18
|
* [0.7.0] - 2017-02-18
|
||||||
|
|
||||||
|
|
|
@ -58,13 +58,6 @@ public interface Node<T> {
|
||||||
*/
|
*/
|
||||||
Optional<T> findData();
|
Optional<T> findData();
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch the data held within the node.
|
|
||||||
*
|
|
||||||
* @return the node's data, or throws an {@link EmptyNodeException}
|
|
||||||
*/
|
|
||||||
T getData();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the data held within the node.
|
* Set the data held within the node.
|
||||||
*
|
*
|
||||||
|
@ -93,13 +86,6 @@ public interface Node<T> {
|
||||||
*/
|
*/
|
||||||
Optional<Node<T>> findParent();
|
Optional<Node<T>> findParent();
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetch the parent node.
|
|
||||||
*
|
|
||||||
* @return the parent node, or throws an {@link OrphanedNodeException}
|
|
||||||
*/
|
|
||||||
Node<T> getParent();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the current node a direct child of the parent.
|
* Make the current node a direct child of the parent.
|
||||||
*
|
*
|
||||||
|
@ -157,15 +143,6 @@ public interface Node<T> {
|
||||||
*/
|
*/
|
||||||
Optional<Node<T>> findChild(T child);
|
Optional<Node<T>> findChild(T child);
|
||||||
|
|
||||||
/**
|
|
||||||
* Fetches the node for the child if present.
|
|
||||||
*
|
|
||||||
* @param child the child's data to search for
|
|
||||||
*
|
|
||||||
* @return the child node if found
|
|
||||||
*/
|
|
||||||
Node<T> getChild(T child);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the node is an ancestor.
|
* Checks if the node is an ancestor.
|
||||||
*
|
*
|
||||||
|
@ -202,25 +179,6 @@ public interface Node<T> {
|
||||||
*/
|
*/
|
||||||
Optional<Node<T>> findChildByName(String name);
|
Optional<Node<T>> findChildByName(String name);
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the child with the given name. If one can't be found a
|
|
||||||
* NodeException is thrown.
|
|
||||||
*
|
|
||||||
* @param name the name of the child
|
|
||||||
*
|
|
||||||
* @return the node
|
|
||||||
*/
|
|
||||||
Node<T> getChildByName(String name);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Draw a representation of the tree.
|
|
||||||
*
|
|
||||||
* @param depth current depth for recursion
|
|
||||||
*
|
|
||||||
* @return a representation of the tree
|
|
||||||
*/
|
|
||||||
String drawTree(int depth);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the Node has a name. Where a name supplier is used, the
|
* Returns true if the Node has a name. Where a name supplier is used, the
|
||||||
* generated name is used.
|
* generated name is used.
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
package net.kemitix.node;
|
package net.kemitix.node;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
|
import lombok.Setter;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -38,15 +40,17 @@ import static net.kemitix.node.HeadTail.tail;
|
||||||
*
|
*
|
||||||
* @author Paul Campbell (pcampbell@kemitix.net)
|
* @author Paul Campbell (pcampbell@kemitix.net)
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("methodcount")
|
|
||||||
class NodeItem<T> implements Node<T> {
|
class NodeItem<T> implements Node<T> {
|
||||||
|
|
||||||
private final Set<Node<T>> children = new HashSet<>();
|
private final Set<Node<T>> children = new HashSet<>();
|
||||||
|
|
||||||
|
@Setter
|
||||||
private T data;
|
private T data;
|
||||||
|
|
||||||
private Node<T> parent;
|
private Node<T> parent;
|
||||||
|
|
||||||
|
@Setter
|
||||||
|
@Getter
|
||||||
private String name;
|
private String name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -57,14 +61,21 @@ class NodeItem<T> implements Node<T> {
|
||||||
* @param parent the parent of the node, or null for a root node
|
* @param parent the parent of the node, or null for a root node
|
||||||
* @param children the children of the node - must not be null
|
* @param children the children of the node - must not be null
|
||||||
*/
|
*/
|
||||||
NodeItem(final T data, final String name, final Node<T> parent, @NonNull final Set<Node<T>> children) {
|
NodeItem(
|
||||||
|
final T data,
|
||||||
|
final String name,
|
||||||
|
final Node<T> parent,
|
||||||
|
final Set<Node<T>> children
|
||||||
|
) {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
if (parent != null) {
|
if (parent != null) {
|
||||||
doSetParent(parent);
|
doSetParent(parent);
|
||||||
}
|
}
|
||||||
|
if (children != null) {
|
||||||
this.children.addAll(children);
|
this.children.addAll(children);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the parent of a node without updating the parent in the process as {@link #setParent(Node)} does.
|
* Sets the parent of a node without updating the parent in the process as {@link #setParent(Node)} does.
|
||||||
|
@ -75,34 +86,11 @@ class NodeItem<T> implements Node<T> {
|
||||||
this.parent = newParent;
|
this.parent = newParent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setName(final String name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<T> findData() {
|
public Optional<T> findData() {
|
||||||
return Optional.ofNullable(data);
|
return Optional.ofNullable(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public T getData() {
|
|
||||||
if (isEmpty()) {
|
|
||||||
throw new EmptyNodeException(getName());
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setData(final T data) {
|
|
||||||
this.data = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEmpty() {
|
public boolean isEmpty() {
|
||||||
return data == null;
|
return data == null;
|
||||||
|
@ -118,14 +106,6 @@ class NodeItem<T> implements Node<T> {
|
||||||
return Optional.ofNullable(parent);
|
return Optional.ofNullable(parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node<T> getParent() {
|
|
||||||
if (parent == null) {
|
|
||||||
throw new OrphanedNodeException(getName());
|
|
||||||
}
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Make the current node a direct child of the parent.
|
* Make the current node a direct child of the parent.
|
||||||
*
|
*
|
||||||
|
@ -137,7 +117,7 @@ class NodeItem<T> implements Node<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("npathcomplexity")
|
@SuppressWarnings("npathcomplexity")
|
||||||
private void doSetParent(@NonNull final Node<T> newParent) {
|
private void doSetParent(final Node<T> newParent) {
|
||||||
if (this.equals(newParent) || newParent.isDescendantOf(this)) {
|
if (this.equals(newParent) || newParent.isDescendantOf(this)) {
|
||||||
throw new NodeException("Parent is a descendant");
|
throw new NodeException("Parent is a descendant");
|
||||||
}
|
}
|
||||||
|
@ -178,7 +158,7 @@ class NodeItem<T> implements Node<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyChildIsNotAnAncestor(final @NonNull Node<T> child) {
|
private void verifyChildIsNotAnAncestor(final Node<T> child) {
|
||||||
if (this.equals(child) || isDescendantOf(child)) {
|
if (this.equals(child) || isDescendantOf(child)) {
|
||||||
throw new NodeException("Child is an ancestor");
|
throw new NodeException("Child is an ancestor");
|
||||||
}
|
}
|
||||||
|
@ -237,11 +217,6 @@ class NodeItem<T> implements Node<T> {
|
||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node<T> getChild(final T child) {
|
|
||||||
return findChild(child).orElseThrow(() -> new NodeException("Child not found"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if the node is an ancestor.
|
* Checks if the node is an ancestor.
|
||||||
*
|
*
|
||||||
|
@ -323,33 +298,6 @@ class NodeItem<T> implements Node<T> {
|
||||||
.findAny();
|
.findAny();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Node<T> getChildByName(final String named) {
|
|
||||||
final Optional<Node<T>> optional = findChildByName(named);
|
|
||||||
if (optional.isPresent()) {
|
|
||||||
return optional.get();
|
|
||||||
}
|
|
||||||
throw new NodeException("Named child not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@SuppressWarnings("movevariableinsideif")
|
|
||||||
public String drawTree(final int depth) {
|
|
||||||
final StringBuilder sb = new StringBuilder();
|
|
||||||
final String unnamed = "(unnamed)";
|
|
||||||
if (isNamed()) {
|
|
||||||
sb.append(formatByDepth(name, depth));
|
|
||||||
} else if (!children.isEmpty()) {
|
|
||||||
sb.append(formatByDepth(unnamed, depth));
|
|
||||||
}
|
|
||||||
getChildren().forEach(c -> sb.append(c.drawTree(depth + 1)));
|
|
||||||
return sb.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String formatByDepth(final String value, final int depth) {
|
|
||||||
return String.format("[%1$" + (depth + value.length()) + "s]\n", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNamed() {
|
public boolean isNamed() {
|
||||||
String currentName = getName();
|
String currentName = getName();
|
||||||
|
|
|
@ -123,4 +123,30 @@ public final class Nodes {
|
||||||
getImmutableChildren(source)
|
getImmutableChildren(source)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw a representation of the tree.
|
||||||
|
*
|
||||||
|
* @param depth current depth for recursion
|
||||||
|
* @return a representation of the tree
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("movevariableinsideif")
|
||||||
|
public static <T> String drawTree(
|
||||||
|
final Node<T> node,
|
||||||
|
final int depth
|
||||||
|
) {
|
||||||
|
final StringBuilder sb = new StringBuilder();
|
||||||
|
final String unnamed = "(unnamed)";
|
||||||
|
if (node.isNamed()) {
|
||||||
|
sb.append(formatByDepth(node.getName(), depth));
|
||||||
|
} else if (!node.getChildren().isEmpty()) {
|
||||||
|
sb.append(formatByDepth(unnamed, depth));
|
||||||
|
}
|
||||||
|
node.getChildren().forEach(c -> sb.append(drawTree(c, depth + 1)));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String formatByDepth(final String value, final int depth) {
|
||||||
|
return String.format("[%1$" + (depth + value.length()) + "s]\n", value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
@ -33,18 +34,6 @@ public class ImmutableNodeItemTest {
|
||||||
exception.expectMessage(IMMUTABLE_OBJECT);
|
exception.expectMessage(IMMUTABLE_OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDataReturnsData() {
|
|
||||||
//given
|
|
||||||
val data = "this immutableNode data";
|
|
||||||
//when
|
|
||||||
immutableNode = Nodes.asImmutable(Nodes.unnamedRoot(data));
|
|
||||||
//then
|
|
||||||
assertThat(immutableNode.getData()).as("can get the data from a immutableNode")
|
|
||||||
.
|
|
||||||
contains(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canCreateAnEmptyAndUnnamedNode() {
|
public void canCreateAnEmptyAndUnnamedNode() {
|
||||||
//when
|
//when
|
||||||
|
@ -81,14 +70,15 @@ public class ImmutableNodeItemTest {
|
||||||
@Test
|
@Test
|
||||||
public void shouldContainImmutableCopyOfChild() {
|
public void shouldContainImmutableCopyOfChild() {
|
||||||
//given
|
//given
|
||||||
val parent = Nodes.unnamedRoot("root");
|
Node<String> parent = Nodes.unnamedRoot("root");
|
||||||
val child = Nodes.namedChild("child", "child", parent);
|
Node<String> child = Nodes.namedChild("child", "child", parent);
|
||||||
//when
|
//when
|
||||||
immutableNode = Nodes.asImmutable(parent);
|
immutableNode = Nodes.asImmutable(parent);
|
||||||
//then
|
//then
|
||||||
val immutableChild = immutableNode.getChildByName("child");
|
Optional<Node<String>> immutableChild =
|
||||||
assertThat(immutableChild).isNotSameAs(child);
|
immutableNode.findChildByName("child");
|
||||||
assertThat(immutableChild.getName()).isEqualTo("child");
|
assertThat(immutableChild).isNotEqualTo(Optional.of(child));
|
||||||
|
assertThat(immutableChild.map(Node::getName)).contains("child");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -100,13 +90,14 @@ public class ImmutableNodeItemTest {
|
||||||
immutableNode = Nodes.asImmutable(parent);
|
immutableNode = Nodes.asImmutable(parent);
|
||||||
//then
|
//then
|
||||||
// get the immutable node's child's parent
|
// get the immutable node's child's parent
|
||||||
val immutableChild = immutableNode.getChildByName("child");
|
Optional<Node<String>> foundParent =
|
||||||
final Optional<Node<String>> optionalParent = immutableChild.findParent();
|
immutableNode.findChildByName("child")
|
||||||
if (optionalParent.isPresent()) {
|
.flatMap(Node::findParent);
|
||||||
val p = optionalParent.get();
|
assertThat(foundParent).isNotEmpty();
|
||||||
assertThat(p).hasFieldOrPropertyWithValue("name", "root")
|
foundParent.ifPresent(p ->
|
||||||
.hasFieldOrPropertyWithValue("data", "parent");
|
assertThat(p)
|
||||||
}
|
.hasFieldOrPropertyWithValue("name", "root")
|
||||||
|
.hasFieldOrPropertyWithValue("data", "parent"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -215,10 +206,9 @@ public class ImmutableNodeItemTest {
|
||||||
val result = immutableNode.findChild("child");
|
val result = immutableNode.findChild("child");
|
||||||
//then
|
//then
|
||||||
assertThat(result.isPresent()).isTrue();
|
assertThat(result.isPresent()).isTrue();
|
||||||
if (result.isPresent()) {
|
result.map(resultNode ->
|
||||||
assertThat(result.get()
|
assertThat(resultNode.findData())
|
||||||
.getData()).contains("child");
|
.contains("child"));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -244,9 +234,10 @@ public class ImmutableNodeItemTest {
|
||||||
root.addChild(beta);
|
root.addChild(beta);
|
||||||
immutableNode = Nodes.asImmutable(root);
|
immutableNode = Nodes.asImmutable(root);
|
||||||
//when
|
//when
|
||||||
val result = immutableNode.getChildByName("alpha");
|
Optional<Node<String>> result = immutableNode.findChildByName("alpha");
|
||||||
//then
|
//then
|
||||||
assertThat(result.getName()).isEqualTo(alpha.getName());
|
assertThat(result.map(Node::getName))
|
||||||
|
.contains(alpha.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -257,11 +248,10 @@ public class ImmutableNodeItemTest {
|
||||||
val beta = Nodes.namedRoot("beta data", "beta");
|
val beta = Nodes.namedRoot("beta data", "beta");
|
||||||
root.addChild(alpha);
|
root.addChild(alpha);
|
||||||
root.addChild(beta);
|
root.addChild(beta);
|
||||||
exception.expect(NodeException.class);
|
|
||||||
exception.expectMessage("Named child not found");
|
|
||||||
immutableNode = Nodes.asImmutable(root);
|
immutableNode = Nodes.asImmutable(root);
|
||||||
//when
|
//then
|
||||||
immutableNode.getChildByName("gamma");
|
assertThat(immutableNode.findChildByName("gamma"))
|
||||||
|
.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -316,27 +306,6 @@ public class ImmutableNodeItemTest {
|
||||||
immutableNode.removeChild(null);
|
immutableNode.removeChild(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void drawTreeIsCorrect() {
|
|
||||||
//given
|
|
||||||
val root = Nodes.namedRoot("root data", "root");
|
|
||||||
val bob = Nodes.namedChild("bob data", "bob", root);
|
|
||||||
val alice = Nodes.namedChild("alice data", "alice", root);
|
|
||||||
Nodes.namedChild("dave data", "dave", alice);
|
|
||||||
Nodes.unnamedChild("bob's child's data", bob); // has no name and no children so no included
|
|
||||||
val kim = Nodes.unnamedChild("kim data", root); // nameless mother
|
|
||||||
Nodes.namedChild("lucy data", "lucy", kim);
|
|
||||||
immutableNode = Nodes.asImmutable(root);
|
|
||||||
//when
|
|
||||||
val tree = immutableNode.drawTree(0);
|
|
||||||
//then
|
|
||||||
String[] lines = tree.split("\n");
|
|
||||||
assertThat(lines).contains("[root]", "[ alice]", "[ dave]", "[ (unnamed)]", "[ lucy]", "[ bob]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ alice]", "[ dave]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ (unnamed)]", "[ lucy]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ bob]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void setDataShouldThrowException() {
|
public void setDataShouldThrowException() {
|
||||||
//given
|
//given
|
||||||
|
@ -355,28 +324,6 @@ public class ImmutableNodeItemTest {
|
||||||
immutableNode.createChild("child data", "child name");
|
immutableNode.createChild("child data", "child name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canGetChildWhenFound() {
|
|
||||||
//given
|
|
||||||
val root = Nodes.unnamedRoot("data");
|
|
||||||
val child = Nodes.namedChild("child data", "child name", root);
|
|
||||||
immutableNode = Nodes.asImmutable(root);
|
|
||||||
//when
|
|
||||||
val found = immutableNode.getChild("child data");
|
|
||||||
//then
|
|
||||||
assertThat(found.getName()).isEqualTo(child.getName());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canGetChildWhenNotFound() {
|
|
||||||
//given
|
|
||||||
exception.expect(NodeException.class);
|
|
||||||
exception.expectMessage("Child not found");
|
|
||||||
immutableNode = Nodes.asImmutable(Nodes.unnamedRoot("data"));
|
|
||||||
//when
|
|
||||||
immutableNode.getChild("child data");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canSafelyHandleFindChildWhenAChildHasNoData() {
|
public void canSafelyHandleFindChildWhenAChildHasNoData() {
|
||||||
//given
|
//given
|
||||||
|
@ -437,15 +384,16 @@ public class ImmutableNodeItemTest {
|
||||||
Nodes.namedChild("eight", "eight", n6);
|
Nodes.namedChild("eight", "eight", n6);
|
||||||
val immutableRoot = Nodes.asImmutable(node);
|
val immutableRoot = Nodes.asImmutable(node);
|
||||||
//when
|
//when
|
||||||
val result = immutableRoot.stream()
|
val result = immutableRoot.stream().collect(Collectors.toList());
|
||||||
.collect(Collectors.toList());
|
|
||||||
//then
|
//then
|
||||||
assertThat(result).as("full tree")
|
assertThat(result).as("full tree").hasSize(9);
|
||||||
.hasSize(9);
|
|
||||||
// and
|
// and
|
||||||
assertThat(immutableRoot.getChild("one")
|
assertThat(immutableRoot
|
||||||
.stream()
|
.findChild("one")
|
||||||
.collect(Collectors.toList())).as("sub-tree")
|
.map(Node::stream)
|
||||||
.hasSize(4);
|
.map(Stream::count)
|
||||||
|
)
|
||||||
|
.as("sub-tree")
|
||||||
|
.contains(4L);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
src/test/java/net/kemitix/node/IsNamedCategory.java
Normal file
4
src/test/java/net/kemitix/node/IsNamedCategory.java
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
package net.kemitix.node;
|
||||||
|
|
||||||
|
public interface IsNamedCategory {
|
||||||
|
}
|
|
@ -27,27 +27,6 @@ public class NodeItemTest {
|
||||||
|
|
||||||
private Node<String> node;
|
private Node<String> node;
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDataReturnsData() {
|
|
||||||
//given
|
|
||||||
val data = "this node data";
|
|
||||||
//when
|
|
||||||
node = Nodes.unnamedRoot(data);
|
|
||||||
//then
|
|
||||||
assertThat(node.getData()).as("can get the data from a node")
|
|
||||||
.contains(data);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getDataWhenEmptyThrowsException() throws Exception {
|
|
||||||
//given
|
|
||||||
node = Nodes.unnamedRoot(null);
|
|
||||||
assertThat(node.isEmpty()).isTrue();
|
|
||||||
exception.expect(EmptyNodeException.class);
|
|
||||||
//when
|
|
||||||
node.getData();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findDataWhenFullReturnsData() {
|
public void findDataWhenFullReturnsData() {
|
||||||
//given
|
//given
|
||||||
|
@ -69,26 +48,6 @@ public class NodeItemTest {
|
||||||
assertThat(result).isEmpty();
|
assertThat(result).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getParentWhenRootThrowsException() {
|
|
||||||
//given
|
|
||||||
node = Nodes.unnamedRoot(null);
|
|
||||||
exception.expect(OrphanedNodeException.class);
|
|
||||||
//when
|
|
||||||
node.getParent();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getParentWhenChildReturnsRoot() {
|
|
||||||
//given
|
|
||||||
val root = Nodes.unnamedRoot("root");
|
|
||||||
node = Nodes.unnamedChild("child", root);
|
|
||||||
//when
|
|
||||||
val result = node.getParent();
|
|
||||||
//then
|
|
||||||
assertThat(result).isSameAs(root);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void findParentWhenRootReturnsEmptyOptional() {
|
public void findParentWhenRootReturnsEmptyOptional() {
|
||||||
//given
|
//given
|
||||||
|
@ -607,34 +566,6 @@ public class NodeItemTest {
|
||||||
assertThat(node.findData()).isEmpty();
|
assertThat(node.findData()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getChildNamedFindsChild() {
|
|
||||||
//given
|
|
||||||
node = Nodes.namedRoot("root data", "root");
|
|
||||||
val alpha = Nodes.namedRoot("alpha data", "alpha");
|
|
||||||
val beta = Nodes.namedRoot("beta data", "beta");
|
|
||||||
node.addChild(alpha);
|
|
||||||
node.addChild(beta);
|
|
||||||
//when
|
|
||||||
val result = node.getChildByName("alpha");
|
|
||||||
//then
|
|
||||||
assertThat(result).isSameAs(alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void getChildNamedFindsNothing() {
|
|
||||||
//given
|
|
||||||
node = Nodes.namedRoot("root data", "root");
|
|
||||||
val alpha = Nodes.namedRoot("alpha data", "alpha");
|
|
||||||
val beta = Nodes.namedRoot("beta data", "beta");
|
|
||||||
node.addChild(alpha);
|
|
||||||
node.addChild(beta);
|
|
||||||
exception.expect(NodeException.class);
|
|
||||||
exception.expectMessage("Named child not found");
|
|
||||||
//when
|
|
||||||
node.getChildByName("gamma");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void nodeNamesAreUniqueWithinAParent() {
|
public void nodeNamesAreUniqueWithinAParent() {
|
||||||
//given
|
//given
|
||||||
|
@ -656,23 +587,38 @@ public class NodeItemTest {
|
||||||
//when
|
//when
|
||||||
node.insertInPath(four, "one", "two", "three");
|
node.insertInPath(four, "one", "two", "three");
|
||||||
//then
|
//then
|
||||||
val three = four.getParent();
|
assertThat(four.findParent())
|
||||||
assertThat(four.getParent()).as("add node to a tree")
|
.as("add node to a tree")
|
||||||
.isNotNull();
|
.isNotEmpty();
|
||||||
assertThat(three.getName()).isEqualTo("three");
|
|
||||||
val two = three.getParent();
|
val three = four.findParent();
|
||||||
assertThat(two.getName()).isEqualTo("two");
|
assertThat(three).isNotEmpty();
|
||||||
val one = two.getParent();
|
three.map(threeNode ->
|
||||||
assertThat(one.getName()).isEqualTo("one");
|
assertThat(threeNode.getName())
|
||||||
assertThat(one.getParent()).isSameAs(node);
|
.isEqualTo("three"));
|
||||||
assertThat(node.getChildByName("one")
|
|
||||||
.getChildByName("two")
|
val two = three.flatMap(Node::findParent);
|
||||||
.getChildByName("three")
|
assertThat(two).isNotEmpty();
|
||||||
.getChildByName("four")).isSameAs(four);
|
two.map(twoNode ->
|
||||||
|
assertThat(twoNode.getName())
|
||||||
|
.isEqualTo("two"));
|
||||||
|
|
||||||
|
val one = two.flatMap(Node::findParent);
|
||||||
|
assertThat(one).isNotEmpty();
|
||||||
|
one.ifPresent(oneNode ->
|
||||||
|
SoftAssertions.assertSoftly(softly -> {
|
||||||
|
assertThat(oneNode.getName()).isEqualTo("one");
|
||||||
|
assertThat(oneNode.findParent()).contains(node);
|
||||||
|
}));
|
||||||
|
Optional<Node<String>> fourNode = node.findChildByName("one")
|
||||||
|
.flatMap(oneChild -> oneChild.findChildByName("two"))
|
||||||
|
.flatMap(twoChild -> twoChild.findChildByName("three"))
|
||||||
|
.flatMap(threeChild -> threeChild.findChildByName("four"));
|
||||||
|
assertThat(fourNode).isNotEmpty();
|
||||||
|
assertThat(fourNode).contains(four);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void canPlaceInTreeUnderExistingNode() {
|
public void canPlaceInTreeUnderExistingNode() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.namedRoot(null, "root");
|
node = Nodes.namedRoot(null, "root");
|
||||||
|
@ -682,15 +628,17 @@ public class NodeItemTest {
|
||||||
node.insertInPath(child); // as root/child
|
node.insertInPath(child); // as root/child
|
||||||
node.insertInPath(grandchild, "child"); // as root/child/grandchild
|
node.insertInPath(grandchild, "child"); // as root/child/grandchild
|
||||||
//then
|
//then
|
||||||
assertThat(node.getChildByName("child")).as("child")
|
assertThat(node.findChildByName("child"))
|
||||||
.isSameAs(child);
|
.as("child")
|
||||||
assertThat(node.getChildByName("child")
|
.contains(child);
|
||||||
.getChildByName("grandchild")).as("grandchild")
|
Optional<Node<String>> grandNode = node.findChildByName("child")
|
||||||
.isSameAs(grandchild);
|
.flatMap(childNode -> childNode.findChildByName("grandchild"));
|
||||||
|
assertThat(grandNode)
|
||||||
|
.as("grandchild")
|
||||||
|
.contains(grandchild);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void canPlaceInTreeAboveExistingNode() {
|
public void canPlaceInTreeAboveExistingNode() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.namedRoot(null, "root");
|
node = Nodes.namedRoot(null, "root");
|
||||||
|
@ -700,12 +648,14 @@ public class NodeItemTest {
|
||||||
node.insertInPath(grandchild, "child");
|
node.insertInPath(grandchild, "child");
|
||||||
node.insertInPath(child);
|
node.insertInPath(child);
|
||||||
//then
|
//then
|
||||||
assertThat(node.getChildByName("child")
|
assertThat(node.findChildByName("child").flatMap(Node::findData))
|
||||||
.getData()).as("data in tree")
|
.as("data in tree")
|
||||||
.contains("child data");
|
.contains("child data");
|
||||||
assertThat(node.getChildByName("child")
|
assertThat(
|
||||||
.getChildByName("grandchild")).as("grandchild")
|
node.findChildByName("child").flatMap(childNode ->
|
||||||
.isSameAs(grandchild);
|
childNode.findChildByName("grandchild")))
|
||||||
|
.as("grandchild")
|
||||||
|
.contains(grandchild);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -756,7 +706,6 @@ public class NodeItemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public void placeNodeInTreeWhenEmptyChildWithTargetNameExists() {
|
public void placeNodeInTreeWhenEmptyChildWithTargetNameExists() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.unnamedRoot(null);
|
node = Nodes.unnamedRoot(null);
|
||||||
|
@ -764,17 +713,17 @@ public class NodeItemTest {
|
||||||
final Node<String> target = Nodes.namedRoot(null, "target");
|
final Node<String> target = Nodes.namedRoot(null, "target");
|
||||||
node.addChild(child);
|
node.addChild(child);
|
||||||
child.addChild(target);
|
child.addChild(target);
|
||||||
val addMe = Nodes.namedRoot("I'm new", "target");
|
Node<String> addMe = Nodes.namedRoot("I'm new", "target");
|
||||||
assertThat(addMe.findParent()).isEmpty();
|
assertThat(addMe.findParent()).isEmpty();
|
||||||
assertThat(child.getChildByName("target")
|
assertThat(child.findChildByName("target").flatMap(Node::findData))
|
||||||
.isEmpty()).as("target starts empty")
|
.as("target starts empty")
|
||||||
.isTrue();
|
.isEmpty();
|
||||||
//when
|
//when
|
||||||
// addMe should replace target as the sole descendant of child
|
// addMe should replace target as the sole descendant of child
|
||||||
node.insertInPath(addMe, "child");
|
node.insertInPath(addMe, "child");
|
||||||
//then
|
//then
|
||||||
assertThat(child.getChildByName("target")
|
assertThat(child.findChildByName("target").flatMap(Node::findData))
|
||||||
.getData()).as("target now contains data")
|
.as("target now contains data")
|
||||||
.contains("I'm new");
|
.contains("I'm new");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -789,14 +738,16 @@ public class NodeItemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Category(IsNamedCategory.class)
|
||||||
public void isNamedNull() {
|
public void isNamedNull() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.unnamedRoot(null);
|
node = Nodes.namedRoot(null, null);
|
||||||
//then
|
//then
|
||||||
assertThat(node.isNamed()).isFalse();
|
assertThat(node.isNamed()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Category(IsNamedCategory.class)
|
||||||
public void isNamedEmpty() {
|
public void isNamedEmpty() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.namedRoot(null, "");
|
node = Nodes.namedRoot(null, "");
|
||||||
|
@ -805,6 +756,7 @@ public class NodeItemTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@Category(IsNamedCategory.class)
|
||||||
public void isNamedNamed() {
|
public void isNamedNamed() {
|
||||||
//given
|
//given
|
||||||
node = Nodes.namedRoot(null, "named");
|
node = Nodes.namedRoot(null, "named");
|
||||||
|
@ -826,26 +778,6 @@ public class NodeItemTest {
|
||||||
assertThat(child.findParent()).isEmpty();
|
assertThat(child.findParent()).isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void drawTreeIsCorrect() {
|
|
||||||
//given
|
|
||||||
node = Nodes.namedRoot(null, "root");
|
|
||||||
val bob = Nodes.namedChild("bob data", "bob", node);
|
|
||||||
val alice = Nodes.namedChild("alice data", "alice", node);
|
|
||||||
Nodes.namedChild("dave data", "dave", alice);
|
|
||||||
Nodes.unnamedChild("bob's child's data", bob); // has no name and no children so no included
|
|
||||||
val kim = Nodes.unnamedChild("kim data", node); // nameless mother
|
|
||||||
Nodes.namedChild("lucy data", "lucy", kim);
|
|
||||||
//when
|
|
||||||
val tree = node.drawTree(0);
|
|
||||||
//then
|
|
||||||
String[] lines = tree.split("\n");
|
|
||||||
assertThat(lines).contains("[root]", "[ alice]", "[ dave]", "[ (unnamed)]", "[ lucy]", "[ bob]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ alice]", "[ dave]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ (unnamed)]", "[ lucy]");
|
|
||||||
assertThat(lines).containsSubsequence("[root]", "[ bob]");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void canChangeNodeData() {
|
public void canChangeNodeData() {
|
||||||
//given
|
//given
|
||||||
|
@ -853,7 +785,7 @@ public class NodeItemTest {
|
||||||
//when
|
//when
|
||||||
node.setData("updated");
|
node.setData("updated");
|
||||||
//then
|
//then
|
||||||
assertThat(node.getData()).contains("updated");
|
assertThat(node.findData()).contains("updated");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -869,27 +801,6 @@ public class NodeItemTest {
|
||||||
assertThat(node.getChildren()).containsExactly(child);
|
assertThat(node.getChildren()).containsExactly(child);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canGetChildWhenFound() {
|
|
||||||
//given
|
|
||||||
node = Nodes.unnamedRoot("data");
|
|
||||||
val child = Nodes.namedChild("child data", "child name", node);
|
|
||||||
//when
|
|
||||||
val found = node.getChild("child data");
|
|
||||||
//then
|
|
||||||
assertThat(found).isSameAs(child);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canGetChildWhenNotFound() {
|
|
||||||
//given
|
|
||||||
exception.expect(NodeException.class);
|
|
||||||
exception.expectMessage("Child not found");
|
|
||||||
node = Nodes.unnamedRoot("data");
|
|
||||||
//when
|
|
||||||
node.getChild("child data");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public void constructorWithNameSupplierAndParentBeChildOfParent() {
|
public void constructorWithNameSupplierAndParentBeChildOfParent() {
|
||||||
|
@ -969,4 +880,17 @@ public class NodeItemTest {
|
||||||
assertThat(resultChild1).containsExactlyInAnyOrder(root);
|
assertThat(resultChild1).containsExactlyInAnyOrder(root);
|
||||||
assertThat(resultChild3).containsExactlyInAnyOrder(child2, root);
|
assertThat(resultChild3).containsExactlyInAnyOrder(child2, root);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void whenNodeItemChildrenAreNullThenAsNoChildren() {
|
||||||
|
//when
|
||||||
|
NodeItem<String> nodeItem = new NodeItem<>(
|
||||||
|
"data",
|
||||||
|
"name",
|
||||||
|
null,
|
||||||
|
null);
|
||||||
|
//then
|
||||||
|
assertThat(nodeItem.getChildren())
|
||||||
|
.isEmpty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
30
src/test/java/net/kemitix/node/NodeTreeDrawTest.java
Normal file
30
src/test/java/net/kemitix/node/NodeTreeDrawTest.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
package net.kemitix.node;
|
||||||
|
|
||||||
|
import lombok.val;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
public class NodeTreeDrawTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void drawTreeIsCorrect() {
|
||||||
|
//given
|
||||||
|
final Node<String> node = Nodes.namedRoot(null, "root");
|
||||||
|
val bob = Nodes.namedChild("bob data", "bob", node);
|
||||||
|
val alice = Nodes.namedChild("alice data", "alice", node);
|
||||||
|
Nodes.namedChild("dave data", "dave", alice);
|
||||||
|
Nodes.unnamedChild("bob's child's data", bob); // has no name and no children so no included
|
||||||
|
val kim = Nodes.unnamedChild("kim data", node); // nameless mother
|
||||||
|
Nodes.namedChild("lucy data", "lucy", kim);
|
||||||
|
//when
|
||||||
|
val tree = Nodes.drawTree(node, 0);
|
||||||
|
//then
|
||||||
|
String[] lines = tree.split("\n");
|
||||||
|
assertThat(lines).contains("[root]", "[ alice]", "[ dave]", "[ (unnamed)]", "[ lucy]", "[ bob]");
|
||||||
|
assertThat(lines).containsSubsequence("[root]", "[ alice]", "[ dave]");
|
||||||
|
assertThat(lines).containsSubsequence("[root]", "[ (unnamed)]", "[ lucy]");
|
||||||
|
assertThat(lines).containsSubsequence("[root]", "[ bob]");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -23,7 +23,7 @@ public class NodesTest {
|
||||||
public void shouldCreateUnnamedRoot() throws Exception {
|
public void shouldCreateUnnamedRoot() throws Exception {
|
||||||
val node = Nodes.unnamedRoot("data");
|
val node = Nodes.unnamedRoot("data");
|
||||||
SoftAssertions softly = new SoftAssertions();
|
SoftAssertions softly = new SoftAssertions();
|
||||||
softly.assertThat(node.getData()).contains("data");
|
softly.assertThat(node.findData()).contains("data");
|
||||||
softly.assertThat(node.getName()).isEmpty();
|
softly.assertThat(node.getName()).isEmpty();
|
||||||
softly.assertAll();
|
softly.assertAll();
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ public class NodesTest {
|
||||||
public void shouldCreateNamedRoot() throws Exception {
|
public void shouldCreateNamedRoot() throws Exception {
|
||||||
val node = Nodes.namedRoot("data", "name");
|
val node = Nodes.namedRoot("data", "name");
|
||||||
SoftAssertions softly = new SoftAssertions();
|
SoftAssertions softly = new SoftAssertions();
|
||||||
softly.assertThat(node.getData()).contains("data");
|
softly.assertThat(node.findData()).contains("data");
|
||||||
softly.assertThat(node.getName()).isEqualTo("name");
|
softly.assertThat(node.getName()).isEqualTo("name");
|
||||||
softly.assertAll();
|
softly.assertAll();
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ public class NodesTest {
|
||||||
val parent = Nodes.unnamedRoot("root");
|
val parent = Nodes.unnamedRoot("root");
|
||||||
val node = Nodes.unnamedChild("data", parent);
|
val node = Nodes.unnamedChild("data", parent);
|
||||||
SoftAssertions softly = new SoftAssertions();
|
SoftAssertions softly = new SoftAssertions();
|
||||||
softly.assertThat(node.getData()).contains("data");
|
softly.assertThat(node.findData()).contains("data");
|
||||||
softly.assertThat(node.getName()).isEmpty();
|
softly.assertThat(node.getName()).isEmpty();
|
||||||
softly.assertThat(node.findParent()).contains(parent);
|
softly.assertThat(node.findParent()).contains(parent);
|
||||||
softly.assertAll();
|
softly.assertAll();
|
||||||
|
@ -53,7 +53,7 @@ public class NodesTest {
|
||||||
val parent = Nodes.unnamedRoot("root");
|
val parent = Nodes.unnamedRoot("root");
|
||||||
val node = Nodes.namedChild("data", "child", parent);
|
val node = Nodes.namedChild("data", "child", parent);
|
||||||
SoftAssertions softly = new SoftAssertions();
|
SoftAssertions softly = new SoftAssertions();
|
||||||
softly.assertThat(node.getData()).contains("data");
|
softly.assertThat(node.findData()).contains("data");
|
||||||
softly.assertThat(node.getName()).isEqualTo("child");
|
softly.assertThat(node.getName()).isEqualTo("child");
|
||||||
softly.assertThat(node.findParent()).contains(parent);
|
softly.assertThat(node.findParent()).contains(parent);
|
||||||
softly.assertAll();
|
softly.assertAll();
|
||||||
|
|
Loading…
Reference in a new issue