diff --git a/CHANGELOG.org b/CHANGELOG.org index 2ad153e..b8ce4a1 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -9,16 +9,29 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ** Added -- Add kemitix-maven-tiles +- Add kemitix-maven-tiles 2.4.1 ** Changed - Replace Jenkins with Github Actions (#57) - [checkstyle] suppress npath complexity issues - [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 +- 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 lombok from 1.18.8 to 1.18.10 (#49) - 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 tiles-maven-plugin from 2.12 to 2.13 (#40) - 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 diff --git a/src/main/java/net/kemitix/node/Node.java b/src/main/java/net/kemitix/node/Node.java index 62bf838..f9bdcca 100644 --- a/src/main/java/net/kemitix/node/Node.java +++ b/src/main/java/net/kemitix/node/Node.java @@ -58,13 +58,6 @@ public interface Node { */ Optional 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. * @@ -93,13 +86,6 @@ public interface Node { */ Optional> findParent(); - /** - * Fetch the parent node. - * - * @return the parent node, or throws an {@link OrphanedNodeException} - */ - Node getParent(); - /** * Make the current node a direct child of the parent. * @@ -157,15 +143,6 @@ public interface Node { */ Optional> 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 getChild(T child); - /** * Checks if the node is an ancestor. * @@ -202,25 +179,6 @@ public interface Node { */ Optional> 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 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 * generated name is used. diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java index 5fc9ffe..b705457 100644 --- a/src/main/java/net/kemitix/node/NodeItem.java +++ b/src/main/java/net/kemitix/node/NodeItem.java @@ -21,7 +21,9 @@ package net.kemitix.node; +import lombok.Getter; import lombok.NonNull; +import lombok.Setter; import lombok.val; import java.util.*; @@ -38,15 +40,17 @@ import static net.kemitix.node.HeadTail.tail; * * @author Paul Campbell (pcampbell@kemitix.net) */ -@SuppressWarnings("methodcount") class NodeItem implements Node { private final Set> children = new HashSet<>(); + @Setter private T data; private Node parent; + @Setter + @Getter private String name; /** @@ -57,13 +61,20 @@ class NodeItem implements 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 */ - NodeItem(final T data, final String name, final Node parent, @NonNull final Set> children) { + NodeItem( + final T data, + final String name, + final Node parent, + final Set> children + ) { this.data = data; this.name = name; if (parent != null) { doSetParent(parent); } - this.children.addAll(children); + if (children != null) { + this.children.addAll(children); + } } /** @@ -75,34 +86,11 @@ class NodeItem implements Node { this.parent = newParent; } - @Override - public String getName() { - return name; - } - - @Override - public void setName(final String name) { - this.name = name; - } - @Override public Optional findData() { 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 public boolean isEmpty() { return data == null; @@ -118,14 +106,6 @@ class NodeItem implements Node { return Optional.ofNullable(parent); } - @Override - public Node getParent() { - if (parent == null) { - throw new OrphanedNodeException(getName()); - } - return parent; - } - /** * Make the current node a direct child of the parent. * @@ -137,7 +117,7 @@ class NodeItem implements Node { } @SuppressWarnings("npathcomplexity") - private void doSetParent(@NonNull final Node newParent) { + private void doSetParent(final Node newParent) { if (this.equals(newParent) || newParent.isDescendantOf(this)) { throw new NodeException("Parent is a descendant"); } @@ -178,7 +158,7 @@ class NodeItem implements Node { } } - private void verifyChildIsNotAnAncestor(final @NonNull Node child) { + private void verifyChildIsNotAnAncestor(final Node child) { if (this.equals(child) || isDescendantOf(child)) { throw new NodeException("Child is an ancestor"); } @@ -237,11 +217,6 @@ class NodeItem implements Node { .findFirst(); } - @Override - public Node getChild(final T child) { - return findChild(child).orElseThrow(() -> new NodeException("Child not found")); - } - /** * Checks if the node is an ancestor. * @@ -323,33 +298,6 @@ class NodeItem implements Node { .findAny(); } - @Override - public Node getChildByName(final String named) { - final Optional> 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 public boolean isNamed() { String currentName = getName(); diff --git a/src/main/java/net/kemitix/node/Nodes.java b/src/main/java/net/kemitix/node/Nodes.java index bf1ae0c..e25dca0 100644 --- a/src/main/java/net/kemitix/node/Nodes.java +++ b/src/main/java/net/kemitix/node/Nodes.java @@ -85,7 +85,7 @@ public final class Nodes { */ public static Node namedChild( final T data, final String name, final Node parent - ) { + ) { return new NodeItem<>(data, name, parent, new HashSet<>()); } @@ -104,23 +104,49 @@ public final class Nodes { } final Set> children = getImmutableChildren(root); return ImmutableNodeItem.newRoot(root.findData() - .orElse(null), root.getName(), children); + .orElse(null), root.getName(), children); } private static Set> getImmutableChildren(final Node source) { return source.getChildren() - .stream() - .map(Nodes::asImmutableChild) - .collect(Collectors.toSet()); + .stream() + .map(Nodes::asImmutableChild) + .collect(Collectors.toSet()); } private static Node asImmutableChild( final Node source - ) { + ) { return ImmutableNodeItem.newChild(source.findData() - .orElse(null), source.getName(), source.findParent() - .orElse(null), - getImmutableChildren(source) - ); + .orElse(null), source.getName(), source.findParent() + .orElse(null), + getImmutableChildren(source) + ); + } + + /** + * Draw a representation of the tree. + * + * @param depth current depth for recursion + * @return a representation of the tree + */ + @SuppressWarnings("movevariableinsideif") + public static String drawTree( + final Node 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); } } diff --git a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java index 7454e05..63d3b00 100644 --- a/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java +++ b/src/test/java/net/kemitix/node/ImmutableNodeItemTest.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.Collections; import java.util.Optional; import java.util.stream.Collectors; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; @@ -33,18 +34,6 @@ public class ImmutableNodeItemTest { 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 public void canCreateAnEmptyAndUnnamedNode() { //when @@ -81,14 +70,15 @@ public class ImmutableNodeItemTest { @Test public void shouldContainImmutableCopyOfChild() { //given - val parent = Nodes.unnamedRoot("root"); - val child = Nodes.namedChild("child", "child", parent); + Node parent = Nodes.unnamedRoot("root"); + Node child = Nodes.namedChild("child", "child", parent); //when immutableNode = Nodes.asImmutable(parent); //then - val immutableChild = immutableNode.getChildByName("child"); - assertThat(immutableChild).isNotSameAs(child); - assertThat(immutableChild.getName()).isEqualTo("child"); + Optional> immutableChild = + immutableNode.findChildByName("child"); + assertThat(immutableChild).isNotEqualTo(Optional.of(child)); + assertThat(immutableChild.map(Node::getName)).contains("child"); } @Test @@ -100,13 +90,14 @@ public class ImmutableNodeItemTest { immutableNode = Nodes.asImmutable(parent); //then // get the immutable node's child's parent - val immutableChild = immutableNode.getChildByName("child"); - final Optional> optionalParent = immutableChild.findParent(); - if (optionalParent.isPresent()) { - val p = optionalParent.get(); - assertThat(p).hasFieldOrPropertyWithValue("name", "root") - .hasFieldOrPropertyWithValue("data", "parent"); - } + Optional> foundParent = + immutableNode.findChildByName("child") + .flatMap(Node::findParent); + assertThat(foundParent).isNotEmpty(); + foundParent.ifPresent(p -> + assertThat(p) + .hasFieldOrPropertyWithValue("name", "root") + .hasFieldOrPropertyWithValue("data", "parent")); } @Test @@ -215,10 +206,9 @@ public class ImmutableNodeItemTest { val result = immutableNode.findChild("child"); //then assertThat(result.isPresent()).isTrue(); - if (result.isPresent()) { - assertThat(result.get() - .getData()).contains("child"); - } + result.map(resultNode -> + assertThat(resultNode.findData()) + .contains("child")); } /** @@ -244,9 +234,10 @@ public class ImmutableNodeItemTest { root.addChild(beta); immutableNode = Nodes.asImmutable(root); //when - val result = immutableNode.getChildByName("alpha"); + Optional> result = immutableNode.findChildByName("alpha"); //then - assertThat(result.getName()).isEqualTo(alpha.getName()); + assertThat(result.map(Node::getName)) + .contains(alpha.getName()); } @Test @@ -257,11 +248,10 @@ public class ImmutableNodeItemTest { val beta = Nodes.namedRoot("beta data", "beta"); root.addChild(alpha); root.addChild(beta); - exception.expect(NodeException.class); - exception.expectMessage("Named child not found"); immutableNode = Nodes.asImmutable(root); - //when - immutableNode.getChildByName("gamma"); + //then + assertThat(immutableNode.findChildByName("gamma")) + .isEmpty(); } @Test @@ -316,27 +306,6 @@ public class ImmutableNodeItemTest { 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 public void setDataShouldThrowException() { //given @@ -355,28 +324,6 @@ public class ImmutableNodeItemTest { 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 public void canSafelyHandleFindChildWhenAChildHasNoData() { //given @@ -437,15 +384,16 @@ public class ImmutableNodeItemTest { Nodes.namedChild("eight", "eight", n6); val immutableRoot = Nodes.asImmutable(node); //when - val result = immutableRoot.stream() - .collect(Collectors.toList()); + val result = immutableRoot.stream().collect(Collectors.toList()); //then - assertThat(result).as("full tree") - .hasSize(9); + assertThat(result).as("full tree").hasSize(9); // and - assertThat(immutableRoot.getChild("one") - .stream() - .collect(Collectors.toList())).as("sub-tree") - .hasSize(4); + assertThat(immutableRoot + .findChild("one") + .map(Node::stream) + .map(Stream::count) + ) + .as("sub-tree") + .contains(4L); } } diff --git a/src/test/java/net/kemitix/node/IsNamedCategory.java b/src/test/java/net/kemitix/node/IsNamedCategory.java new file mode 100644 index 0000000..13eeacf --- /dev/null +++ b/src/test/java/net/kemitix/node/IsNamedCategory.java @@ -0,0 +1,4 @@ +package net.kemitix.node; + +public interface IsNamedCategory { +} diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java index 89d2d78..2fd0194 100644 --- a/src/test/java/net/kemitix/node/NodeItemTest.java +++ b/src/test/java/net/kemitix/node/NodeItemTest.java @@ -27,27 +27,6 @@ public class NodeItemTest { private Node 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 public void findDataWhenFullReturnsData() { //given @@ -69,26 +48,6 @@ public class NodeItemTest { 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 public void findParentWhenRootReturnsEmptyOptional() { //given @@ -607,34 +566,6 @@ public class NodeItemTest { 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 public void nodeNamesAreUniqueWithinAParent() { //given @@ -656,23 +587,38 @@ public class NodeItemTest { //when node.insertInPath(four, "one", "two", "three"); //then - val three = four.getParent(); - assertThat(four.getParent()).as("add node to a tree") - .isNotNull(); - assertThat(three.getName()).isEqualTo("three"); - val two = three.getParent(); - assertThat(two.getName()).isEqualTo("two"); - val one = two.getParent(); - assertThat(one.getName()).isEqualTo("one"); - assertThat(one.getParent()).isSameAs(node); - assertThat(node.getChildByName("one") - .getChildByName("two") - .getChildByName("three") - .getChildByName("four")).isSameAs(four); + assertThat(four.findParent()) + .as("add node to a tree") + .isNotEmpty(); + + val three = four.findParent(); + assertThat(three).isNotEmpty(); + three.map(threeNode -> + assertThat(threeNode.getName()) + .isEqualTo("three")); + + val two = three.flatMap(Node::findParent); + assertThat(two).isNotEmpty(); + 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> 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 - @SuppressWarnings("unchecked") public void canPlaceInTreeUnderExistingNode() { //given node = Nodes.namedRoot(null, "root"); @@ -682,15 +628,17 @@ public class NodeItemTest { node.insertInPath(child); // as root/child node.insertInPath(grandchild, "child"); // as root/child/grandchild //then - assertThat(node.getChildByName("child")).as("child") - .isSameAs(child); - assertThat(node.getChildByName("child") - .getChildByName("grandchild")).as("grandchild") - .isSameAs(grandchild); + assertThat(node.findChildByName("child")) + .as("child") + .contains(child); + Optional> grandNode = node.findChildByName("child") + .flatMap(childNode -> childNode.findChildByName("grandchild")); + assertThat(grandNode) + .as("grandchild") + .contains(grandchild); } @Test - @SuppressWarnings("unchecked") public void canPlaceInTreeAboveExistingNode() { //given node = Nodes.namedRoot(null, "root"); @@ -700,12 +648,14 @@ public class NodeItemTest { node.insertInPath(grandchild, "child"); node.insertInPath(child); //then - assertThat(node.getChildByName("child") - .getData()).as("data in tree") - .contains("child data"); - assertThat(node.getChildByName("child") - .getChildByName("grandchild")).as("grandchild") - .isSameAs(grandchild); + assertThat(node.findChildByName("child").flatMap(Node::findData)) + .as("data in tree") + .contains("child data"); + assertThat( + node.findChildByName("child").flatMap(childNode -> + childNode.findChildByName("grandchild"))) + .as("grandchild") + .contains(grandchild); } @Test @@ -756,7 +706,6 @@ public class NodeItemTest { } @Test - @SuppressWarnings("unchecked") public void placeNodeInTreeWhenEmptyChildWithTargetNameExists() { //given node = Nodes.unnamedRoot(null); @@ -764,18 +713,18 @@ public class NodeItemTest { final Node target = Nodes.namedRoot(null, "target"); node.addChild(child); child.addChild(target); - val addMe = Nodes.namedRoot("I'm new", "target"); + Node addMe = Nodes.namedRoot("I'm new", "target"); assertThat(addMe.findParent()).isEmpty(); - assertThat(child.getChildByName("target") - .isEmpty()).as("target starts empty") - .isTrue(); + assertThat(child.findChildByName("target").flatMap(Node::findData)) + .as("target starts empty") + .isEmpty(); //when // addMe should replace target as the sole descendant of child node.insertInPath(addMe, "child"); //then - assertThat(child.getChildByName("target") - .getData()).as("target now contains data") - .contains("I'm new"); + assertThat(child.findChildByName("target").flatMap(Node::findData)) + .as("target now contains data") + .contains("I'm new"); } @Test @@ -789,14 +738,16 @@ public class NodeItemTest { } @Test + @Category(IsNamedCategory.class) public void isNamedNull() { //given - node = Nodes.unnamedRoot(null); + node = Nodes.namedRoot(null, null); //then assertThat(node.isNamed()).isFalse(); } @Test + @Category(IsNamedCategory.class) public void isNamedEmpty() { //given node = Nodes.namedRoot(null, ""); @@ -805,6 +756,7 @@ public class NodeItemTest { } @Test + @Category(IsNamedCategory.class) public void isNamedNamed() { //given node = Nodes.namedRoot(null, "named"); @@ -826,26 +778,6 @@ public class NodeItemTest { 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 public void canChangeNodeData() { //given @@ -853,7 +785,7 @@ public class NodeItemTest { //when node.setData("updated"); //then - assertThat(node.getData()).contains("updated"); + assertThat(node.findData()).contains("updated"); } @Test @@ -869,27 +801,6 @@ public class NodeItemTest { 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 @SuppressWarnings("unchecked") public void constructorWithNameSupplierAndParentBeChildOfParent() { @@ -969,4 +880,17 @@ public class NodeItemTest { assertThat(resultChild1).containsExactlyInAnyOrder(root); assertThat(resultChild3).containsExactlyInAnyOrder(child2, root); } + + @Test + public void whenNodeItemChildrenAreNullThenAsNoChildren() { + //when + NodeItem nodeItem = new NodeItem<>( + "data", + "name", + null, + null); + //then + assertThat(nodeItem.getChildren()) + .isEmpty(); + } } diff --git a/src/test/java/net/kemitix/node/NodeTreeDrawTest.java b/src/test/java/net/kemitix/node/NodeTreeDrawTest.java new file mode 100644 index 0000000..33c6c2b --- /dev/null +++ b/src/test/java/net/kemitix/node/NodeTreeDrawTest.java @@ -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 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]"); + } + +} diff --git a/src/test/java/net/kemitix/node/NodesTest.java b/src/test/java/net/kemitix/node/NodesTest.java index e8badef..5251587 100644 --- a/src/test/java/net/kemitix/node/NodesTest.java +++ b/src/test/java/net/kemitix/node/NodesTest.java @@ -23,7 +23,7 @@ public class NodesTest { public void shouldCreateUnnamedRoot() throws Exception { val node = Nodes.unnamedRoot("data"); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(node.getData()).contains("data"); + softly.assertThat(node.findData()).contains("data"); softly.assertThat(node.getName()).isEmpty(); softly.assertAll(); } @@ -32,7 +32,7 @@ public class NodesTest { public void shouldCreateNamedRoot() throws Exception { val node = Nodes.namedRoot("data", "name"); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(node.getData()).contains("data"); + softly.assertThat(node.findData()).contains("data"); softly.assertThat(node.getName()).isEqualTo("name"); softly.assertAll(); } @@ -42,7 +42,7 @@ public class NodesTest { val parent = Nodes.unnamedRoot("root"); val node = Nodes.unnamedChild("data", parent); SoftAssertions softly = new SoftAssertions(); - softly.assertThat(node.getData()).contains("data"); + softly.assertThat(node.findData()).contains("data"); softly.assertThat(node.getName()).isEmpty(); softly.assertThat(node.findParent()).contains(parent); softly.assertAll(); @@ -53,7 +53,7 @@ public class NodesTest { val parent = Nodes.unnamedRoot("root"); val node = Nodes.namedChild("data", "child", parent); 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.findParent()).contains(parent); softly.assertAll();