diff --git a/pom.xml b/pom.xml
index dd9ddbf..3071a0d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,6 +17,7 @@
3.4.1
4.2.0
+ 2.1.0
@@ -69,5 +70,11 @@
${assertj.version}
test
+
+ net.trajano.commons
+ commons-testing
+ ${trajano-commons-testing.version}
+ test
+
diff --git a/src/main/java/net/kemitix/node/NodeItem.java b/src/main/java/net/kemitix/node/NodeItem.java
index ec71f11..1a83c73 100644
--- a/src/main/java/net/kemitix/node/NodeItem.java
+++ b/src/main/java/net/kemitix/node/NodeItem.java
@@ -32,7 +32,7 @@ public class NodeItem implements Node {
* @param data the data or null
* @param name the name
*/
- public NodeItem(final T data, final String name) {
+ NodeItem(final T data, final String name) {
this(data);
this.name = name;
}
@@ -42,30 +42,18 @@ public class NodeItem implements Node {
*
* @param data the data or null
*/
- public NodeItem(final T data) {
+ NodeItem(final T data) {
this.data = data;
this.nameSupplier = (n) -> null;
}
- /**
- * Creates root node with a name supplier.
- *
- * @param data the data or null
- * @param nameSupplier the name supplier function
- */
- public NodeItem(
- final T data, final Function, String> nameSupplier) {
- this(data);
- this.nameSupplier = nameSupplier;
- }
-
/**
* Creates a node with a parent.
*
* @param data the data or null
* @param parent the parent node
*/
- public NodeItem(final T data, final Node parent) {
+ NodeItem(final T data, final Node parent) {
this.data = data;
setParent(parent);
}
@@ -77,26 +65,12 @@ public class NodeItem implements Node {
* @param name the name
* @param parent the parent node
*/
- public NodeItem(final T data, final String name, final Node parent) {
+ NodeItem(final T data, final String name, final Node parent) {
this.data = data;
this.name = name;
setParent(parent);
}
- /**
- * Creates a node with a name supplier and a parent.
- *
- * @param data the data or null
- * @param nameSupplier the name supplier function
- * @param parent the parent node
- */
- public NodeItem(
- final T data, final Function, String> nameSupplier,
- final Node parent) {
- this(data, nameSupplier);
- setParent(parent);
- }
-
private String generateName() {
return getNameSupplier().apply(this);
}
@@ -229,6 +203,7 @@ public class NodeItem implements Node {
* @return the found or created child node
*/
@Override
+ @Deprecated
public Node findOrCreateChild(final T child) {
if (child == null) {
throw new NullPointerException("child");
@@ -248,10 +223,10 @@ public class NodeItem implements Node {
if (child == null) {
throw new NullPointerException("child");
}
- return children.stream()
- .filter(n -> !n.isEmpty())
- .filter(n -> n.getData().get().equals(child))
- .findAny();
+ return children.stream().filter(node -> {
+ final Optional d = node.getData();
+ return d.isPresent() && d.get().equals(child);
+ }).findAny();
}
@Override
diff --git a/src/main/java/net/kemitix/node/Nodes.java b/src/main/java/net/kemitix/node/Nodes.java
new file mode 100644
index 0000000..24dc50e
--- /dev/null
+++ b/src/main/java/net/kemitix/node/Nodes.java
@@ -0,0 +1,66 @@
+package net.kemitix.node;
+
+/**
+ * Utility class for {@link Node} items.
+ *
+ * @author pcampbell
+ */
+public final class Nodes {
+
+ private Nodes() {
+ }
+
+ /**
+ * Creates a new unnamed root node.
+ *
+ * @param data the data the node will contain
+ * @param the type of the data
+ *
+ * @return the new node
+ */
+ public static Node unnamedRoot(final T data) {
+ return new NodeItem<>(data);
+ }
+
+ /**
+ * Creates a new named root node.
+ *
+ * @param data the data the node will contain
+ * @param name the name of the node
+ * @param the type of the data
+ *
+ * @return the new node
+ */
+ public static Node namedRoot(final T data, final String name) {
+ return new NodeItem<>(data, name);
+ }
+
+ /**
+ * Creates a new unnamed child node.
+ *
+ * @param data the data the node will contain
+ * @param parent the parent of the node
+ * @param the type of the data
+ *
+ * @return the new node
+ */
+ public static Node unnamedChild(final T data, final Node parent) {
+ return new NodeItem<>(data, parent);
+ }
+
+ /**
+ * Creates a new named child node.
+ *
+ * @param data the data the node will contain
+ * @param name the name of the node
+ * @param parent the parent of the node
+ * @param the type of the data
+ *
+ * @return the new node
+ */
+ public static Node namedChild(
+ final T data, final String name, final Node parent) {
+ return new NodeItem<>(data, name, parent);
+ }
+
+}
diff --git a/src/test/java/net/kemitix/node/NodeItemTest.java b/src/test/java/net/kemitix/node/NodeItemTest.java
index 700b053..247e7fb 100644
--- a/src/test/java/net/kemitix/node/NodeItemTest.java
+++ b/src/test/java/net/kemitix/node/NodeItemTest.java
@@ -8,13 +8,9 @@ import org.junit.rules.ExpectedException;
import static org.assertj.core.api.Assertions.assertThat;
-import java.time.LocalDate;
-import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Function;
/**
* Test for {@link NodeItem}.
@@ -33,7 +29,7 @@ public class NodeItemTest {
//given
val data = "this node data";
//when
- node = new NodeItem<>(data);
+ node = Nodes.unnamedRoot(data);
//then
assertThat(node.getData()).as("can get the data from a node").
contains(data);
@@ -42,7 +38,7 @@ public class NodeItemTest {
@Test
public void canCreateAnEmptyAndUnnamedNode() {
//when
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//then
SoftAssertions softly = new SoftAssertions();
softly.assertThat(node.isEmpty()).as("node is empty").isTrue();
@@ -50,21 +46,10 @@ public class NodeItemTest {
softly.assertAll();
}
- @Test
- public void canCreateNodeWithParentAndCustomNameSupplier() {
- //given
- node = new NodeItem<>(null, n -> "root name supplier");
- //when
- val child = new NodeItem(null, n -> "overridden", node);
- //then
- assertThat(child.getName()).isEqualTo("overridden");
- assertThat(child.getParent()).contains(node);
- }
-
@Test
public void canSetName() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//when
node.setName("named");
//then
@@ -77,7 +62,7 @@ public class NodeItemTest {
@Test
public void shouldHaveNullForDefaultParent() {
//given
- node = new NodeItem<>("data");
+ node = Nodes.unnamedRoot("data");
//then
assertThat(node.getParent()).as(
"node created without a parent has no parent").isEmpty();
@@ -89,9 +74,9 @@ public class NodeItemTest {
@Test
public void shouldReturnNodeParent() {
//given
- val parent = new NodeItem("parent");
+ val parent = Nodes.unnamedRoot("parent");
//when
- node = new NodeItem<>("subject", parent);
+ node = Nodes.unnamedChild("subject", parent);
//then
assertThat(node.getParent()).as(
"node created with a parent can return the parent")
@@ -105,8 +90,8 @@ public class NodeItemTest {
@Test
public void setParentShouldThrowNodeExceptionWhenParentIsAChild() {
//given
- node = new NodeItem<>("subject");
- val child = new NodeItem("child", node);
+ node = Nodes.unnamedRoot("subject");
+ val child = Nodes.unnamedChild("child", node);
exception.expect(NodeException.class);
exception.expectMessage("Parent is a descendant");
//when
@@ -121,9 +106,9 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void shouldAddNewNodeAsChildToParent() {
//given
- val parent = new NodeItem("parent");
+ val parent = Nodes.unnamedRoot("parent");
//when
- node = new NodeItem<>("subject", parent);
+ node = Nodes.unnamedChild("subject", parent);
//then
assertThat(parent.getChildren()).as(
"when a node is created with a parent, the parent has the new"
@@ -136,8 +121,8 @@ public class NodeItemTest {
@Test
public void shouldReturnSetParent() {
//given
- node = new NodeItem<>("subject");
- val parent = new NodeItem("parent");
+ node = Nodes.unnamedRoot("subject");
+ val parent = Nodes.unnamedRoot("parent");
//when
node.setParent(parent);
//then
@@ -152,7 +137,7 @@ public class NodeItemTest {
@Test
public void shouldThrowNPEWhenSetParentNull() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("parent");
//when
@@ -166,7 +151,7 @@ public class NodeItemTest {
@Test
public void setParentShouldThrowNodeExceptionWhenParentIsSelf() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NodeException.class);
exception.expectMessage("Parent is a descendant");
//when
@@ -180,9 +165,9 @@ public class NodeItemTest {
@Test
public void shouldUpdateOldParentWhenNodeSetToNewParent() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val child = node.createChild("child");
- val newParent = new NodeItem("newParent");
+ val newParent = Nodes.unnamedRoot("newParent");
//when
child.setParent(newParent);
//then
@@ -201,9 +186,9 @@ public class NodeItemTest {
@Test
public void shouldRemoveNodeFromOldParentWhenAddedAsChildToNewParent() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val child = node.createChild("child");
- val newParent = new NodeItem("newParent");
+ val newParent = Nodes.unnamedRoot("newParent");
//when
newParent.addChild(child);
//then
@@ -223,7 +208,7 @@ public class NodeItemTest {
@Test
public void shouldThrowNPEWhenAddingNullAsChild() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("child");
//when
@@ -237,8 +222,8 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void shouldReturnAddedChild() {
//given
- node = new NodeItem<>("subject");
- val child = new NodeItem("child");
+ node = Nodes.unnamedRoot("subject");
+ val child = Nodes.unnamedRoot("child");
//when
node.addChild(child);
//then
@@ -253,7 +238,7 @@ public class NodeItemTest {
@Test
public void addChildShouldThrowNodeExceptionWhenAddingANodeAsOwnChild() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NodeException.class);
exception.expectMessage("Child is an ancestor");
//then
@@ -266,7 +251,7 @@ public class NodeItemTest {
@Test
public void addChildShouldThrowNodeExceptionWhenAddingSelfAsChild() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NodeException.class);
exception.expectMessage("Child is an ancestor");
//when
@@ -280,8 +265,8 @@ public class NodeItemTest {
@Test
public void addChildShouldThrowNodeExceptionWhenChildIsParent() {
//given
- val parent = new NodeItem("parent");
- node = new NodeItem<>("subject", parent);
+ val parent = Nodes.unnamedRoot("parent");
+ node = Nodes.unnamedChild("subject", parent);
exception.expect(NodeException.class);
exception.expectMessage("Child is an ancestor");
//when
@@ -295,9 +280,9 @@ public class NodeItemTest {
@Test
public void addChildShouldThrowNodeExceptionWhenAddingGrandParentAsChild() {
//given
- val grandParent = new NodeItem("grandparent");
- val parent = new NodeItem("parent", grandParent);
- node = new NodeItem<>("subject", parent);
+ val grandParent = Nodes.unnamedRoot("grandparent");
+ val parent = Nodes.unnamedChild("parent", grandParent);
+ node = Nodes.unnamedChild("subject", parent);
exception.expect(NodeException.class);
exception.expectMessage("Child is an ancestor");
//when
@@ -310,8 +295,8 @@ public class NodeItemTest {
@Test
public void shouldSetParentOnChildWhenAddedAsChild() {
//given
- node = new NodeItem<>("subject");
- val child = new NodeItem("child");
+ node = Nodes.unnamedRoot("subject");
+ val child = Nodes.unnamedRoot("child");
//when
node.addChild(child);
//then
@@ -327,11 +312,11 @@ public class NodeItemTest {
public void shouldWalkTreeToNode() {
//given
val grandparent = "grandparent";
- val grandParentNode = new NodeItem(grandparent);
+ val grandParentNode = Nodes.unnamedRoot(grandparent);
val parent = "parent";
- val parentNode = new NodeItem(parent, grandParentNode);
+ val parentNode = Nodes.unnamedChild(parent, grandParentNode);
val subject = "subject";
- node = new NodeItem<>(subject, parentNode);
+ node = Nodes.unnamedChild(subject, parentNode);
//when
val result = grandParentNode.findInPath(Arrays.asList(parent, subject));
//then
@@ -352,9 +337,9 @@ public class NodeItemTest {
public void shouldNotFindNonExistentChildNode() {
//given
val parent = "parent";
- val parentNode = new NodeItem(parent);
+ val parentNode = Nodes.unnamedRoot(parent);
val subject = "subject";
- node = new NodeItem<>(subject, parentNode);
+ node = Nodes.unnamedChild(subject, parentNode);
//when
val result = parentNode.findInPath(Arrays.asList(subject, "no child"));
//then
@@ -369,7 +354,7 @@ public class NodeItemTest {
@Test
public void shouldThrowNEWhenWalkTreeNull() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("path");
//when
@@ -383,7 +368,7 @@ public class NodeItemTest {
@Test
public void shouldReturnEmptyForEmptyWalkTreePath() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
//when
val result = node.findInPath(Collections.emptyList());
//then
@@ -396,7 +381,7 @@ public class NodeItemTest {
@Test
public void shouldCreateDescendantNodes() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val alphaData = "alpha";
val betaData = "beta";
val gammaData = "gamma";
@@ -445,7 +430,7 @@ public class NodeItemTest {
@Test
public void createDescendantLineShouldThrowNPEWhenDescendantsAreNull() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("descendants");
//when
@@ -458,7 +443,7 @@ public class NodeItemTest {
@Test
public void shouldChangeNothingWhenCreateDescendantEmpty() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
//when
node.createDescendantLine(Collections.emptyList());
//then
@@ -473,9 +458,9 @@ public class NodeItemTest {
@Test
public void shouldFindExistingChildNode() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val childData = "child";
- val child = new NodeItem(childData, node);
+ val child = Nodes.unnamedChild(childData, node);
//when
val found = node.findOrCreateChild(childData);
//then
@@ -490,7 +475,7 @@ public class NodeItemTest {
@Test
public void shouldFindCreateNewChildNode() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val childData = "child";
//when
val found = node.findOrCreateChild(childData);
@@ -506,7 +491,7 @@ public class NodeItemTest {
@Test
public void findOrCreateChildShouldThrowNPEFWhenChildIsNull() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("child");
//when
@@ -519,9 +504,9 @@ public class NodeItemTest {
@Test
public void shouldGetChild() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val childData = "child";
- val child = new NodeItem(childData);
+ val child = Nodes.unnamedRoot(childData);
node.addChild(child);
//when
val found = node.findChild(childData);
@@ -541,7 +526,7 @@ public class NodeItemTest {
@Test
public void getChildShouldThrowNPEWhenThereIsNoChild() {
//given
- node = new NodeItem<>("data");
+ node = Nodes.unnamedRoot("data");
exception.expect(NullPointerException.class);
exception.expectMessage("child");
//when
@@ -555,7 +540,7 @@ public class NodeItemTest {
@Test
public void shouldCreateChild() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
val childData = "child";
//when
val child = node.createChild(childData);
@@ -580,82 +565,25 @@ public class NodeItemTest {
@Test
public void createChildShouldThrowNPEWhenChildIsNull() {
//given
- node = new NodeItem<>("subject");
+ node = Nodes.unnamedRoot("subject");
exception.expect(NullPointerException.class);
exception.expectMessage("child");
//when
node.createChild(null);
}
- @Test
- public void getNameShouldBeCorrect() {
- //given
- node = new NodeItem<>("subject", n -> n.getData().get());
- //then
- assertThat(node.getName()).isEqualTo("subject");
- }
-
- @Test
- public void getNameShouldUseParentNameSupplier() {
- //given
- val root = new NodeItem("root", n -> n.getData().get());
- node = new NodeItem<>("child", root);
- //then
- assertThat(node.getName()).isEqualTo("child");
- }
-
- @Test
- public void getNameShouldReturnNameForNonStringData() {
- val root = new NodeItem(LocalDate.parse("2016-05-23"), n -> {
- if (n.isEmpty()) {
- return null;
- }
- return n.getData().get().format(DateTimeFormatter.BASIC_ISO_DATE);
-
- });
- //then
- assertThat(root.getName()).isEqualTo("20160523");
- }
-
- @Test
- public void getNameShouldUseClosestNameSupplier() {
- node = new NodeItem<>("root", n -> n.getData().get());
- val child = new NodeItem("child", Object::toString);
- node.addChild(child);
- val grandChild = new NodeItem<>("grandchild", child);
- //then
- assertThat(node.getName()).isEqualTo("root");
- assertThat(child.getName()).isNotEqualTo("child");
- assertThat(grandChild.getName()).isNotEqualTo("grandchild");
- }
-
- @Test
- public void getNameShouldWorkWithoutNameSupplier() {
- node = new NodeItem<>(null, "root");
- val namedchild = new NodeItem<>("named", "Alice", node);
- //then
- assertThat(node.getName()).isEqualTo("root");
- assertThat(namedchild.getName()).isEqualTo("Alice");
- }
-
@Test
public void canCreateRootNodeWithoutData() {
- node = new NodeItem<>(null, "empty");
- assertThat(node.getData()).isEmpty();
- }
-
- @Test
- public void canCreateRootNodeWithoutDataButWithNameSupplier() {
- node = new NodeItem<>(null);
+ node = Nodes.namedRoot(null, "empty");
assertThat(node.getData()).isEmpty();
}
@Test
public void getChildNamedFindsChild() {
//given
- node = new NodeItem<>(null, "root");
- val alpha = new NodeItem(null, "alpha");
- val beta = new NodeItem(null, "beta");
+ 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
@@ -667,9 +595,9 @@ public class NodeItemTest {
@Test
public void getChildNamedFindsNothing() {
//given
- node = new NodeItem<>(null, "root");
- val alpha = new NodeItem(null, "alpha");
- val beta = new NodeItem(null, "beta");
+ 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);
@@ -681,10 +609,10 @@ public class NodeItemTest {
@Test
public void nodeNamesAreUniqueWithinAParent() {
//given
- node = new NodeItem<>(null, "root");
- val alpha = new NodeItem(null, "alpha");
+ node = Nodes.namedRoot("root data", "root");
+ val alpha = Nodes.namedRoot("alpha data", "alpha");
node.addChild(alpha);
- val beta = new NodeItem(null, "alpha");
+ val beta = Nodes.namedRoot("beta data", "alpha");
exception.expect(NodeException.class);
exception.expectMessage("Node with that name already exists here");
//when
@@ -694,8 +622,8 @@ public class NodeItemTest {
@Test
public void canPlaceNodeInTreeByPathNames() {
//given
- node = new NodeItem<>(null, "root"); // create a root
- val four = new NodeItem("data", "four");
+ node = Nodes.namedRoot("root data", "root"); // create a root
+ val four = Nodes.namedRoot("data", "four");
//when
node.insertInPath(four, "one", "two", "three");
//then
@@ -717,9 +645,9 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void canPlaceInTreeUnderExistingNode() {
//given
- node = new NodeItem<>(null, "root");
- val child = new NodeItem("child data", "child");
- val grandchild = new NodeItem("grandchild data", "grandchild");
+ node = Nodes.namedRoot(null, "root");
+ val child = Nodes.namedRoot("child data", "child");
+ val grandchild = Nodes.namedRoot("grandchild data", "grandchild");
//when
node.insertInPath(child); // as root/child
node.insertInPath(grandchild, "child"); // as root/child/grandchild
@@ -734,9 +662,9 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void canPlaceInTreeAboveExistingNode() {
//given
- node = new NodeItem<>(null, "root");
- val child = new NodeItem("child data", "child");
- val grandchild = new NodeItem("grandchild data", "grandchild");
+ node = Nodes.namedRoot(null, "root");
+ val child = Nodes.namedRoot("child data", "child");
+ val grandchild = Nodes.namedRoot("grandchild data", "grandchild");
//when
node.insertInPath(grandchild, "child");
node.insertInPath(child);
@@ -752,7 +680,7 @@ public class NodeItemTest {
@Test
public void removingParentFromNodeWithNoParentIsNoop() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//when
node.removeParent();
}
@@ -760,8 +688,8 @@ public class NodeItemTest {
@Test
public void removingParentFromNodeWithParentRemovesParent() {
//given
- node = new NodeItem<>(null);
- val child = new NodeItem(null, node);
+ node = Nodes.unnamedRoot(null);
+ val child = Nodes.unnamedChild("child data", node);
//when
child.removeParent();
//then
@@ -775,22 +703,22 @@ public class NodeItemTest {
exception.expect(NodeException.class);
exception.expectMessage(
"A non-empty node named 'grandchild' already exists here");
- node = new NodeItem<>(null);
- val child = new NodeItem(null, "child", node);
- new NodeItem<>("data", "grandchild", child);
+ node = Nodes.unnamedRoot(null);
+ val child = Nodes.namedChild("child data", "child", node);
+ Nodes.namedChild("data", "grandchild", child);
// root -> child -> grandchild
// only grandchild has data
//when
// attempt to add another node called 'grandchild' to 'child'
- node.insertInPath(new NodeItem<>("cuckoo", "grandchild"), "child");
+ node.insertInPath(Nodes.namedRoot("cuckoo", "grandchild"), "child");
}
@Test
@SuppressWarnings("unchecked")
public void placeNodeInTreeWhenAddedNodeIsUnnamed() {
//given
- node = new NodeItem<>(null);
- final Node newNode = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
+ final Node newNode = Nodes.unnamedRoot(null);
//when
node.insertInPath(newNode);
//then
@@ -801,12 +729,12 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void placeNodeInTreeWhenEmptyChildWithTargetNameExists() {
//given
- node = new NodeItem<>(null);
- final NodeItem child = new NodeItem<>(null, "child");
- final NodeItem target = new NodeItem<>(null, "target");
+ node = Nodes.unnamedRoot(null);
+ final Node child = Nodes.namedRoot(null, "child");
+ final Node target = Nodes.namedRoot(null, "target");
node.addChild(child);
child.addChild(target);
- final NodeItem addMe = new NodeItem<>("I'm new", "target");
+ val addMe = Nodes.namedRoot("I'm new", "target");
assertThat(addMe.getParent()).isEmpty();
assertThat(child.getChildByName("target").isEmpty()).as(
"target starts empty").isTrue();
@@ -823,7 +751,7 @@ public class NodeItemTest {
//given
exception.expect(NullPointerException.class);
exception.expectMessage("name");
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//when
node.findChildByName(null);
}
@@ -831,7 +759,7 @@ public class NodeItemTest {
@Test
public void isNamedNull() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//then
assertThat(node.isNamed()).isFalse();
}
@@ -839,7 +767,7 @@ public class NodeItemTest {
@Test
public void isNamedEmpty() {
//given
- node = new NodeItem<>(null, "");
+ node = Nodes.namedRoot(null, "");
//then
assertThat(node.isNamed()).isFalse();
}
@@ -847,32 +775,16 @@ public class NodeItemTest {
@Test
public void isNamedNamed() {
//given
- node = new NodeItem<>(null, "named");
+ node = Nodes.namedRoot(null, "named");
//then
assertThat(node.isNamed()).isTrue();
}
- @Test
- public void removeParentNodeProvidesSameNameSupplier() {
- // once a node has it's parent removed it should provide a default name
- // provider
- //given
- node = new NodeItem<>("data", n -> n.getData().get());
- final NodeItem child = new NodeItem<>("other", node);
- assertThat(node.getName()).as("initial root name").isEqualTo("data");
- assertThat(child.getName()).as("initial child name").isEqualTo("other");
- //when
- child.removeParent();
- //then
- assertThat(node.getName()).as("final root name").isEqualTo("data");
- assertThat(child.getName()).as("final child name").isEqualTo("other");
- }
-
@Test
@SuppressWarnings("unchecked")
public void removeChildRemovesTheChild() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
Node child = node.createChild("child");
assertThat(node.getChildren()).containsExactly(child);
//then
@@ -885,13 +797,14 @@ public class NodeItemTest {
@Test
public void drawTreeIsCorrect() {
//given
- node = new NodeItem<>(null, "root");
- val bob = new NodeItem(null, "bob", node);
- val alice = new NodeItem(null, "alice", node);
- new NodeItem<>(null, "dave", alice);
- new NodeItem<>(null, bob); // has no name and no children so no included
- val kim = new NodeItem(null, node); // nameless mother
- new NodeItem<>(null, "lucy", kim);
+ 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
@@ -907,7 +820,7 @@ public class NodeItemTest {
@Test
public void canChangeNodeData() {
//given
- node = new NodeItem<>("initial");
+ node = Nodes.unnamedRoot("initial");
//when
node.setData("updated");
//then
@@ -918,7 +831,7 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void canCreateNamedChild() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//when
Node child = node.createChild("child data", "child name");
//then
@@ -930,10 +843,10 @@ public class NodeItemTest {
@Test
public void canGetChildWhenFound() {
//given
- node = new NodeItem<>("data");
- Node child = new NodeItem<>("child data", "child name", node);
+ node = Nodes.unnamedRoot("data");
+ val child = Nodes.namedChild("child data", "child name", node);
//when
- Node found = node.getChild("child data");
+ val found = node.getChild("child data");
//then
assertThat(found).isSameAs(child);
}
@@ -943,7 +856,7 @@ public class NodeItemTest {
//given
exception.expect(NodeException.class);
exception.expectMessage("Child not found");
- node = new NodeItem<>("data");
+ node = Nodes.unnamedRoot("data");
//when
node.getChild("child data");
}
@@ -952,99 +865,19 @@ public class NodeItemTest {
@SuppressWarnings("unchecked")
public void constructorWithNameSupplierAndParentBeChildOfParent() {
//given
- node = new NodeItem<>(null);
+ node = Nodes.unnamedRoot(null);
//when
- NodeItem child = new NodeItem<>(null, node);
+ val child = Nodes.unnamedChild("child data", node);
//then
assertThat(child.getParent()).contains(node);
assertThat(node.getChildren()).containsExactly(child);
}
- @Test
- @SuppressWarnings("unchecked")
- public void removeParentCopiesRootNameSupplier() {
- //given
- node = new NodeItem<>("root data", n -> "root supplier");
- val child = new NodeItem<>("child data", node);
- assertThat(child.getName()).isEqualTo("root supplier");
- //when
- child.removeParent();
- //then
- assertThat(child.getName()).isEqualTo("root supplier");
- }
-
- @Test
- @SuppressWarnings("unchecked")
- public void removeParentDoesNotReplaceLocalNameSupplier() {
- //given
- node = new NodeItem<>("root data", n -> "root supplier");
- val child = new NodeItem<>("child data", n -> "local supplier", node);
- assertThat(child.getName()).isEqualTo("local supplier");
- //when
- child.removeParent();
- //then
- assertThat(child.getName()).isEqualTo("local supplier");
- }
-
- @Test
- public void setNameToNullRevertsToParentNameSupplier() {
- //given
- node = new NodeItem<>(null, n -> "root supplier");
- val child = new NodeItem(null, "child name", node);
- assertThat(child.getName()).isEqualTo("child name");
- //when
- child.setName(null);
- //then
- assertThat(child.getName()).isEqualTo("root supplier");
- }
-
- @Test
- public void getNameWithNameSupplierIsRecalculatedEachCall() {
- val counter = new AtomicInteger(0);
- node = new NodeItem<>(null,
- n -> Integer.toString(counter.incrementAndGet()));
- //then
- assertThat(node.getName()).isNotEqualTo(node.getName());
- }
-
- @Test
- public void isNamedWithNameSupplierIsRecalculatedEachCall() {
- val counter = new AtomicInteger(0);
- node = new NodeItem<>(null, n -> {
- // alternate between even numbers and nulls: null, 2, null, 4, null
- final int i = counter.incrementAndGet();
- if (i % 2 == 0) {
- return Integer.toString(i);
- }
- return null;
- });
- //then
- assertThat(node.isNamed()).isFalse();
- assertThat(node.isNamed()).isTrue();
- }
-
- @Test
- public void canUseNameSupplierToBuildFullPath() {
- //given
- final Function, String> pathNameSupplier = node -> {
- Optional> parent = node.getParent();
- if (parent.isPresent()) {
- return parent.get().getName() + "/" + node.getData().get();
- }
- return "";
- };
- node = new NodeItem<>(null, pathNameSupplier);
- val child = new NodeItem("child", node);
- val grandchild = new NodeItem("grandchild", child);
- //then
- assertThat(grandchild.getName()).isEqualTo("/child/grandchild");
- }
-
@Test
public void canSafelyHandleFindChildWhenAChildHasNoData() {
//given
- node = new NodeItem<>(null);
- new NodeItem<>(null, node);
+ node = Nodes.unnamedRoot(null);
+ Nodes.unnamedChild(null, node);
//when
node.findChild("data");
}
diff --git a/src/test/java/net/kemitix/node/NodesTest.java b/src/test/java/net/kemitix/node/NodesTest.java
new file mode 100644
index 0000000..ace4f79
--- /dev/null
+++ b/src/test/java/net/kemitix/node/NodesTest.java
@@ -0,0 +1,62 @@
+package net.kemitix.node;
+
+import lombok.val;
+import org.assertj.core.api.SoftAssertions;
+import org.junit.Test;
+
+import static net.trajano.commons.testing.UtilityClassTestUtil
+ .assertUtilityClassWellDefined;
+
+/**
+ * Tests for {@link Nodes}.
+ *
+ * @author pcampbell
+ */
+public class NodesTest {
+
+ @Test
+ public void shouldBeValidUtilityClass() throws Exception {
+ assertUtilityClassWellDefined(Nodes.class);
+ }
+
+ @Test
+ public void shouldCreateUnnamedRoot() throws Exception {
+ val node = Nodes.unnamedRoot("data");
+ SoftAssertions softly = new SoftAssertions();
+ softly.assertThat(node.getData()).contains("data");
+ softly.assertThat(node.getName()).isNull();
+ softly.assertAll();
+ }
+
+ @Test
+ public void shouldCreateNamedRoot() throws Exception {
+ val node = Nodes.namedRoot("data", "name");
+ SoftAssertions softly = new SoftAssertions();
+ softly.assertThat(node.getData()).contains("data");
+ softly.assertThat(node.getName()).isEqualTo("name");
+ softly.assertAll();
+ }
+
+ @Test
+ public void shouldCreateUnnamedChild() throws Exception {
+ val parent = Nodes.unnamedRoot("root");
+ val node = Nodes.unnamedChild("data", parent);
+ SoftAssertions softly = new SoftAssertions();
+ softly.assertThat(node.getData()).contains("data");
+ softly.assertThat(node.getName()).isNull();
+ softly.assertThat(node.getParent()).contains(parent);
+ softly.assertAll();
+ }
+
+ @Test
+ public void shouldCreateNamedChild() throws Exception {
+ 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.getName()).isEqualTo("child");
+ softly.assertThat(node.getParent()).contains(parent);
+ softly.assertAll();
+ }
+
+}