package org.jabref.model;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.verify;
@RunWith(MockitoJUnitRunner.class)
public class TreeNodeTest {
@Mock
Consumer<TreeNodeTestData.TreeNodeMock> subscriber;
@Test(expected = UnsupportedOperationException.class)
public void constructorChecksThatClassImplementsCorrectInterface() {
new WrongTreeNodeImplementation();
}
@Test
public void constructorExceptsCorrectImplementation() {
TreeNodeTestData.TreeNodeMock treeNode = new TreeNodeTestData.TreeNodeMock();
assertNotNull(treeNode);
}
@Test
public void newTreeNodeHasNoParentOrChildren() {
TreeNodeTestData.TreeNodeMock treeNode = new TreeNodeTestData.TreeNodeMock();
assertEquals(Optional.empty(), treeNode.getParent());
assertEquals(Collections.emptyList(), treeNode.getChildren());
assertNotNull(treeNode);
}
@Test
public void getIndexedPathFromRootReturnsEmptyListForRoot() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(Collections.emptyList(), root.getIndexedPathFromRoot());
}
@Test
public void getIndexedPathFromRootSimplePath() {
assertEquals(Arrays.asList(1, 0), TreeNodeTestData.getNodeInSimpleTree().getIndexedPathFromRoot());
}
@Test
public void getIndexedPathFromRootComplexPath() {
assertEquals(Arrays.asList(2, 1, 0), TreeNodeTestData.getNodeInComplexTree().getIndexedPathFromRoot());
}
@Test
public void getDescendantSimplePath() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
assertEquals(node, root.getDescendant(Arrays.asList(1, 0)).get());
}
@Test
public void getDescendantComplexPath() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
assertEquals(node, root.getDescendant(Arrays.asList(2, 1, 0)).get());
}
@Test
public void getDescendantNonExistentReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.getNodeInComplexTree(root);
assertEquals(Optional.empty(), root.getDescendant(Arrays.asList(1, 100, 0)));
}
@Test(expected = UnsupportedOperationException.class)
public void getPositionInParentForRootThrowsException() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
root.getPositionInParent();
}
@Test
public void getPositionInParentSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
assertEquals(2, node.getPositionInParent());
}
@Test
public void getIndexOfNonExistentChildReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(Optional.empty(), root.getIndexOfChild(new TreeNodeTestData.TreeNodeMock()));
}
@Test
public void getIndexOfChild() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
assertEquals((Integer)2, root.getIndexOfChild(node).get());
}
@Test
public void getLevelOfRoot() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(0, root.getLevel());
}
@Test
public void getLevelInSimpleTree() {
assertEquals(2, TreeNodeTestData.getNodeInSimpleTree().getLevel());
}
@Test
public void getLevelInComplexTree() {
assertEquals(3, TreeNodeTestData.getNodeInComplexTree().getLevel());
}
@Test
public void getChildCountInSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.getNodeInSimpleTree(root);
assertEquals(2, root.getNumberOfChildren());
}
@Test
public void getChildCountInComplexTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.getNodeInComplexTree(root);
assertEquals(4, root.getNumberOfChildren());
}
@Test
public void moveToAddsAsLastChildInSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
node.moveTo(root);
assertEquals((Integer)2, root.getIndexOfChild(node).get());
}
@Test
public void moveToAddsAsLastChildInComplexTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
node.moveTo(root);
assertEquals((Integer)4, root.getIndexOfChild(node).get());
}
@Test
public void moveToChangesParent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
node.moveTo(root);
assertEquals(root, node.getParent().get());
}
@Test
public void moveToInSameLevelAddsAtEnd() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock();
root.addChild(child1);
root.addChild(child2);
child1.moveTo(root);
assertEquals(Arrays.asList(child2, child1), root.getChildren());
}
@Test
public void getPathFromRootInSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
List<TreeNodeTestData.TreeNodeMock> path = node.getPathFromRoot();
assertEquals(3, path.size());
assertEquals(root, path.get(0));
assertEquals(node, path.get(2));
}
@Test
public void getPathFromRootInComplexTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
List<TreeNodeTestData.TreeNodeMock> path = node.getPathFromRoot();
assertEquals(4, path.size());
assertEquals(root, path.get(0));
assertEquals(node, path.get(3));
}
@Test
public void getPreviousSiblingReturnsCorrect() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
root.addChild(new TreeNodeTestData.TreeNodeMock());
TreeNodeTestData.TreeNodeMock previous = new TreeNodeTestData.TreeNodeMock();
root.addChild(previous);
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
root.addChild(new TreeNodeTestData.TreeNodeMock());
assertEquals(previous, node.getPreviousSibling().get());
}
@Test
public void getPreviousSiblingForRootReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(Optional.empty(), root.getPreviousSibling());
}
@Test
public void getPreviousSiblingForNonexistentReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
assertEquals(Optional.empty(), node.getPreviousSibling());
}
@Test
public void getNextSiblingReturnsCorrect() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
root.addChild(new TreeNodeTestData.TreeNodeMock());
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
TreeNodeTestData.TreeNodeMock next = new TreeNodeTestData.TreeNodeMock();
root.addChild(next);
root.addChild(new TreeNodeTestData.TreeNodeMock());
assertEquals(next, node.getNextSibling().get());
}
@Test
public void getNextSiblingForRootReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(Optional.empty(), root.getNextSibling());
}
@Test
public void getNextSiblingForNonexistentReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
assertEquals(Optional.empty(), node.getPreviousSibling());
}
@Test
public void getParentReturnsCorrect() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
assertEquals(root, node.getParent().get());
}
@Test
public void getParentForRootReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(Optional.empty(), root.getParent());
}
@Test
public void getChildAtReturnsCorrect() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
assertEquals(node, root.getChildAt(2).get());
}
@Test
public void getChildAtInvalidIndexReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
root.addChild(new TreeNodeTestData.TreeNodeMock());
root.addChild(new TreeNodeTestData.TreeNodeMock());
assertEquals(Optional.empty(), root.getChildAt(10));
}
@Test
public void getRootReturnsTrueForRoot() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertTrue(root.isRoot());
}
@Test
public void getRootReturnsFalseForChild() {
assertFalse(TreeNodeTestData.getNodeInSimpleTree().isRoot());
}
@Test
public void nodeIsAncestorOfItself() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertTrue(root.isAncestorOf(root));
}
@Test
public void isAncestorOfInSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
assertTrue(root.isAncestorOf(node));
}
@Test
public void isAncestorOfInComplexTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
assertTrue(root.isAncestorOf(node));
}
@Test
public void getRootOfSingleNode() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertEquals(root, root.getRoot());
}
@Test
public void getRootInSimpleTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
assertEquals(root, node.getRoot());
}
@Test
public void getRootInComplexTree() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
assertEquals(root, node.getRoot());
}
@Test
public void isLeafIsCorrectForRootWithoutChildren() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
assertTrue(root.isLeaf());
}
@Test
public void removeFromParentSetsParentToEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
node.removeFromParent();
assertEquals(Optional.empty(), node.getParent());
}
@Test
public void removeFromParentRemovesNodeFromChildrenCollection() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
node.removeFromParent();
assertFalse(root.getChildren().contains(node));
}
@Test
public void removeAllChildrenSetsParentOfChildToEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.removeAllChildren();
assertEquals(Optional.empty(), node.getParent());
}
@Test
public void removeAllChildrenRemovesAllNodesFromChildrenCollection() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.getNodeAsChild(root);
root.removeAllChildren();
assertEquals(Collections.emptyList(), root.getChildren());
}
@Test
public void getFirstChildAtReturnsCorrect() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
assertEquals(node, root.getFirstChild().get());
}
@Test
public void getFirstChildAtLeafReturnsEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock leaf = TreeNodeTestData.getNodeAsChild(root);
assertEquals(Optional.empty(), leaf.getFirstChild());
}
@Test
public void isNodeDescendantInFirstLevel() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child = TreeNodeTestData.getNodeAsChild(root);
assertTrue(root.isNodeDescendant(child));
}
@Test
public void isNodeDescendantInComplex() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock descendant = TreeNodeTestData.getNodeInComplexTree(root);
assertTrue(root.isNodeDescendant(descendant));
}
@Test
public void getChildrenReturnsAllChildren() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock();
root.addChild(child1);
root.addChild(child2);
assertEquals(Arrays.asList(child1, child2), root.getChildren());
}
@Test
public void removeChildSetsParentToEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.removeChild(node);
assertEquals(Optional.empty(), node.getParent());
}
@Test
public void removeChildRemovesNodeFromChildrenCollection() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.removeChild(node);
assertFalse(root.getChildren().contains(node));
}
@Test
public void removeChildIndexSetsParentToEmpty() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.removeChild(2);
assertEquals(Optional.empty(), node.getParent());
}
@Test
public void removeChildIndexRemovesNodeFromChildrenCollection() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.removeChild(2);
assertFalse(root.getChildren().contains(node));
}
@Test(expected = UnsupportedOperationException.class)
public void addThrowsExceptionIfNodeHasParent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.addChild(node);
}
@Test
public void moveAllChildrenToAddsAtSpecifiedPosition() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock();
node.addChild(child1);
node.addChild(child2);
node.moveAllChildrenTo(root, 0);
assertEquals(Arrays.asList(child1, child2, node), root.getChildren());
}
@Test
public void moveAllChildrenToChangesParent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = new TreeNodeTestData.TreeNodeMock();
root.addChild(node);
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock();
node.addChild(child1);
node.addChild(child2);
node.moveAllChildrenTo(root, 0);
assertEquals(root, child1.getParent().get());
assertEquals(root, child2.getParent().get());
}
@Test(expected = UnsupportedOperationException.class)
public void moveAllChildrenToDescendantThrowsException() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
root.moveAllChildrenTo(node, 0);
}
@Test
public void sortChildrenSortsInFirstLevel() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock("a");
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock("b");
TreeNodeTestData.TreeNodeMock child3 = new TreeNodeTestData.TreeNodeMock("c");
root.addChild(child2);
root.addChild(child3);
root.addChild(child1);
root.sortChildren((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()), false);
assertEquals(Arrays.asList(child1, child2, child3), root.getChildren());
}
@Test
public void sortChildrenRecursiveSortsInDeeperLevel() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInSimpleTree(root);
TreeNodeTestData.TreeNodeMock child1 = new TreeNodeTestData.TreeNodeMock("a");
TreeNodeTestData.TreeNodeMock child2 = new TreeNodeTestData.TreeNodeMock("b");
TreeNodeTestData.TreeNodeMock child3 = new TreeNodeTestData.TreeNodeMock("c");
node.addChild(child2);
node.addChild(child3);
node.addChild(child1);
root.sortChildren((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()), true);
assertEquals(Arrays.asList(child1, child2, child3), node.getChildren());
}
@Test
public void copySubtreeCopiesChildren() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeAsChild(root);
TreeNodeTestData.TreeNodeMock copiedRoot = root.copySubtree();
assertEquals(Optional.empty(), copiedRoot.getParent());
assertFalse(copiedRoot.getChildren().contains(node));
assertEquals(root.getNumberOfChildren(), copiedRoot.getNumberOfChildren());
}
@Test
public void addChildSomewhereInTreeInvokesChangeEvent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
root.subscribeToDescendantChanged(subscriber);
node.addChild(new TreeNodeTestData.TreeNodeMock());
verify(subscriber).accept(node);
}
@Test
public void moveNodeSomewhereInTreeInvokesChangeEvent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
TreeNodeTestData.TreeNodeMock oldParent = node.getParent().get();
root.subscribeToDescendantChanged(subscriber);
node.moveTo(root);
verify(subscriber).accept(root);
verify(subscriber).accept(oldParent);
}
@Test
public void removeChildSomewhereInTreeInvokesChangeEvent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
TreeNodeTestData.TreeNodeMock child = node.addChild(new TreeNodeTestData.TreeNodeMock());
root.subscribeToDescendantChanged(subscriber);
node.removeChild(child);
verify(subscriber).accept(node);
}
@Test
public void removeChildIndexSomewhereInTreeInvokesChangeEvent() {
TreeNodeTestData.TreeNodeMock root = new TreeNodeTestData.TreeNodeMock();
TreeNodeTestData.TreeNodeMock node = TreeNodeTestData.getNodeInComplexTree(root);
node.addChild(new TreeNodeTestData.TreeNodeMock());
root.subscribeToDescendantChanged(subscriber);
node.removeChild(0);
verify(subscriber).accept(node);
}
private static class WrongTreeNodeImplementation extends TreeNode<TreeNodeTestData.TreeNodeMock> {
// This class is a wrong derived class of TreeNode<T>
// since it does not extends TreeNode<WrongTreeNodeImplementation>
// See test constructorChecksThatClassImplementsCorrectInterface
public WrongTreeNodeImplementation() {
super(TreeNodeTestData.TreeNodeMock.class);
}
@Override
public TreeNodeTestData.TreeNodeMock copyNode() {
return null;
}
}
}