diff --git a/src/main/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilter.java b/src/main/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilter.java index 77b1cda..4025f25 100644 --- a/src/main/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilter.java +++ b/src/main/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilter.java @@ -6,7 +6,7 @@ import lombok.NonNull; import javax.swing.tree.MutableTreeNode; -import java.util.ArrayList; +import java.util.*; /** * Filters the "entities" and "entityFields" nodes out of the hierarchy and takes their children to the upper level. @@ -37,6 +37,13 @@ public ArrayList filterChild(@NonNull MutableTreeNode pChild) { for (int i = 0; i < pChild.getChildCount(); i++) list.add(new DiffFilterNode((MutableTreeNode) pChild.getChildAt(i), EntityTreeNodeFilter.this)); + + // Sort alphabetically, to improve readability + list.sort(Comparator.comparing(pNode -> { + if (pNode instanceof DiffFilterNode) + return ((DiffFilterNode) pNode).nameForDisplay(EDirection.LEFT); + return pNode.toString(); + }, String.CASE_INSENSITIVE_ORDER)); } else list.add(new DiffFilterNode(pChild, EntityTreeNodeFilter.this)); diff --git a/src/test/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilterTest.java b/src/test/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilterTest.java new file mode 100644 index 0000000..ec5e223 --- /dev/null +++ b/src/test/java/de/adito/aditoweb/nbm/aliasdiff/impl/gui/EntityTreeNodeFilterTest.java @@ -0,0 +1,91 @@ +package de.adito.aditoweb.nbm.aliasdiff.impl.gui; + +import com.google.common.graph.Traverser; +import de.adito.aditoweb.nbm.aliasdiff.dialog.PropertyNode; +import de.adito.aditoweb.system.crmcomponents.datamodels.entity.provider.IEntityProvider; +import lombok.NonNull; +import org.junit.jupiter.api.*; +import org.mockito.Answers; + +import javax.swing.tree.*; +import java.util.List; +import java.util.stream.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.mockito.Mockito.*; + +/** + * Test for {@link EntityTreeNodeFilter} + * + * @author w.glanzer, 09.08.2023 + * @see EntityTreeNodeFilter + */ +@SuppressWarnings("UnstableApiUsage") +class EntityTreeNodeFilterTest +{ + + private static final Traverser TREE_NODE_TRAVERSER = Traverser.forTree(pNode -> IntStream.range(0, pNode.getChildCount()) + .mapToObj(pNode::getChildAt) + .collect(Collectors.toList())); + + /** + * Test for the method {@link EntityTreeNodeFilter#filterChild(MutableTreeNode)} + */ + @Nested + class FilterChild + { + + /** + * Checks, if (transitive) children gets sorted alphabetically + */ + @Test + void shouldSortAlphabetically() + { + // Create tree structure + DefaultMutableTreeNode root = createTreeNode("root"); + DefaultMutableTreeNode entities = createTreeNode(IEntityProvider.entities.getName()); + root.add(entities); + entities.add(createTreeNode("node1")); + entities.add(createTreeNode("node3")); + entities.add(createTreeNode("node4")); + entities.add(createTreeNode("node2")); + + // filter its children, so they should be sorted now + List nodes = new EntityTreeNodeFilter().filterChild(root); + assertEquals(1, nodes.size()); + assertEquals("root, node1, node2, node3, node4", toString(nodes.get(0))); + } + + /** + * Creates a readable view of the given node and its children + * + * @param pNode Node to get the view from + * @return the view as string + */ + @NonNull + private String toString(@NonNull TreeNode pNode) + { + return StreamSupport.stream(TREE_NODE_TRAVERSER.breadthFirst(pNode).spliterator(), false) + .map(TreeNode::toString) + .collect(Collectors.joining(", ")); + } + + /** + * Creates a {@link DefaultMutableTreeNode} with the given name + * + * @param pName Name that the node should have + * @return the node + */ + @NonNull + private DefaultMutableTreeNode createTreeNode(@NonNull String pName) + { + PropertyNode node = mock(PropertyNode.class, Answers.CALLS_REAL_METHODS); + doReturn(pName).when(node).nameForDisplay(any()); + doReturn(pName).when(node).toString(); + node.setAllowsChildren(true); + return node; + } + + } + +} \ No newline at end of file