/* * Copyright 2016 DiffPlug * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.diffplug.common.base; import java.util.ArrayList; import java.util.List; import org.junit.Assert; import org.junit.Test; public class TreeQueryTest { @Test public void testToRoot() { Assert.assertEquals(root, TreeQuery.root(TreeNode.treeDef(), root)); Assert.assertEquals(root, TreeQuery.root(TreeNode.treeDef(), root.findByContent("src"))); Assert.assertEquals(root, TreeQuery.root(TreeNode.treeDef(), root.findByContent("Array.java"))); } @Test public void testLowestCommonAncestor() { // test the trivial case TreeNode<String> arrayJava = root.findByPath("src", "org", "math", "Array.java"); TreeNode<String> matrixJava = root.findByPath("src", "org", "math", "Matrix.java"); lcaTestCase(root, root, root); lcaTestCase(arrayJava, arrayJava, arrayJava); lcaTestCase(matrixJava, matrixJava, matrixJava); // test the colinear case lcaTestCase(root, arrayJava, root); lcaTestCase(root, matrixJava, root); // test the intersection case lcaTestCase(matrixJava, arrayJava, root.findByPath("src", "org", "math")); } private void lcaTestCase(TreeNode<String> a, TreeNode<String> b, TreeNode<String> expected) { TreeNode<String> actual = TreeQuery.lowestCommonAncestor(TreeNode.treeDef(), a, b).get(); Assert.assertEquals(expected, actual); } @Test public void testPath() { Assert.assertEquals("root", TreeQuery.path(TreeNode.treeDef(), root, TreeNode::getContent)); Assert.assertEquals("root/test/org2/avl/allegro.avl", TreeQuery.path(TreeNode.treeDef(), root.findByContent("allegro.avl"), TreeNode::getContent)); } @Test public void testToString() { // put the testData into its string form String[] pieces = root.toStringDeep().split("\n"); // turn it back into a treeNode TreeNode<String> copiedFromString = TreeNode.createTestData(pieces); // make sure the strings are identical Assert.assertEquals(root.toStringDeep(), copiedFromString.toStringDeep()); // and the same for the underlying tree TreeComparison.of(root, copiedFromString).assertEqual(); } @Test public void testCopyLeavesIn() { testCaseCopyLeavesIn(root); } @Test public void testCopyLeavesInEmpty() { testCaseCopyLeavesIn(new TreeNode<>(null, "")); } private void testCaseCopyLeavesIn(TreeNode<String> copyRoot) { final class Node { final String value; final List<Node> children; public Node(String value, List<Node> children) { this.value = value; this.children = children; } } TreeDef<Node> def = TreeDef.of(node -> node.children); Node copy = TreeQuery.copyLeavesIn(TreeNode.treeDef(), copyRoot, (oldNode, children) -> { return new Node(oldNode.getContent(), children); }); TreeComparison.of(copyRoot, def, copy, node -> node.value).assertEqual(); } @Test public void testCopyRootOut() { testCaseRootOut(root); } @Test public void testCopyRootOutEmpty() { testCaseRootOut(new TreeNode<>(null, "")); } private void testCaseRootOut(TreeNode<String> copyRoot) { final class Node { final String value; final List<Node> children = new ArrayList<>(); public Node(String value, Node parent) { this.value = value; if (parent != null) { parent.children.add(this); } } } TreeDef<Node> def = TreeDef.of(node -> node.children); Node copy = TreeQuery.copyRootOut(TreeNode.treeDef(), copyRoot, (oldNode, parent) -> { return new Node(oldNode.getContent(), parent); }); TreeComparison.of(copyRoot, def, copy, node -> node.value).assertEqual(); } @Test public void testIsDescendantOf() { testCaseIsDescendantOf("root", "root", false); testCaseIsDescendantOf("Vector.java", "Vector.java", false); testCaseIsDescendantOf("src", "root", true); testCaseIsDescendantOf("root", "src", false); testCaseIsDescendantOf("org", "Vector.java", false); testCaseIsDescendantOf("Vector.java", "org", true); } private void testCaseIsDescendantOf(String child, String parent, boolean expected) { boolean actual = TreeQuery.isDescendantOf(TreeNode.treeDef(), root.findByContent(child), root.findByContent(parent)); Assert.assertEquals(expected, actual); } @Test public void testIsDescendantOfOrEqualTo() { testCaseIsDescendantOfOrEqualTo("root", "root", true); testCaseIsDescendantOfOrEqualTo("Vector.java", "Vector.java", true); testCaseIsDescendantOfOrEqualTo("src", "root", true); testCaseIsDescendantOfOrEqualTo("root", "src", false); testCaseIsDescendantOfOrEqualTo("org", "Vector.java", false); testCaseIsDescendantOfOrEqualTo("Vector.java", "org", true); } private void testCaseIsDescendantOfOrEqualTo(String child, String parent, boolean expected) { boolean actual = TreeQuery.isDescendantOfOrEqualTo(TreeNode.treeDef(), root.findByContent(child), root.findByContent(parent)); Assert.assertEquals(expected, actual); } // @formatter:off private TreeNode<String> root = TreeNode.createTestData( "root", " src", " org", " math", " Array.java", " Matrix.java", " QuatRot.java", " Vector.java", " model", " generic", " Constant.java", " Constant.xml", " geometric", " Constant2.java", " Constant2.xml", " Component.java", " DynamicComponent.java", " Folder afterwards", " PerturbDerivative1.java", " PerturbDerivative2.java", " PerturbDerivative3.java", " PerturbDerivative4.java", " PerturbDerivative5.java", " PerturbDerivative6.java", " test", " org2", " avl", " allegro.avl", " allegro.mass", " b737.avl", " simulink", " complex.mdl", " long_simple.mdl", " sf_tetris2.mdl", " RunAllTests.java" ); // @formatter:on }