diff options
Diffstat (limited to 'javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java')
-rw-r--r-- | javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java | 414 |
1 files changed, 414 insertions, 0 deletions
diff --git a/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java new file mode 100644 index 000000000..3201b2910 --- /dev/null +++ b/javaparser-testing/src/test/java/com/github/javaparser/ast/NodeTest.java @@ -0,0 +1,414 @@ +/* + * Copyright (C) 2007-2010 JĂșlio Vilmar Gesser. + * Copyright (C) 2011, 2013-2016 The JavaParser Team. + * + * This file is part of JavaParser. + * + * JavaParser can be used either under the terms of + * a) the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * b) the terms of the Apache License + * + * You should have received a copy of both licenses in LICENCE.LGPL and + * LICENCE.APACHE. Please refer to those files for details. + * + * JavaParser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + */ + +package com.github.javaparser.ast; + +import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; +import com.github.javaparser.ast.body.FieldDeclaration; +import com.github.javaparser.ast.body.MethodDeclaration; +import com.github.javaparser.ast.body.VariableDeclarator; +import com.github.javaparser.ast.comments.BlockComment; +import com.github.javaparser.ast.comments.Comment; +import com.github.javaparser.ast.comments.JavadocComment; +import com.github.javaparser.ast.comments.LineComment; +import com.github.javaparser.ast.expr.Expression; +import com.github.javaparser.ast.expr.IntegerLiteralExpr; +import com.github.javaparser.ast.expr.SimpleName; +import com.github.javaparser.ast.observer.AstObserver; +import com.github.javaparser.ast.observer.AstObserverAdapter; +import com.github.javaparser.ast.observer.ObservableProperty; +import com.github.javaparser.ast.type.PrimitiveType; +import org.junit.Test; + +import java.util.*; +import java.util.stream.Collectors; + +import static com.github.javaparser.JavaParser.parse; +import static com.github.javaparser.JavaParser.parseExpression; +import static com.github.javaparser.utils.Utils.EOL; +import static org.junit.Assert.*; + +public class NodeTest { + + @Test + public void registerSubTree() { + String code = "class A { int f; void foo(int p) { return 'z'; }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + @Override + public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { + changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue)); + } + }; + cu.registerForSubtree(observer); + + assertEquals(Arrays.asList(), changes); + + cu.getClassByName("A").get().setName("MyCoolClass"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN)); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean"), changes); + + cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean", + "Parameter.name changed from p to myParam"), changes); + } + + @Test + public void registerWithJustNodeMode() { + String code = "class A { int f; void foo(int p) { return 'z'; }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + @Override + public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { + changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue)); + } + }; + cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.JUST_THIS_NODE); + + assertEquals(Arrays.asList(), changes); + + cu.getClassByName("A").get().setName("MyCoolClass"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN)); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().addField("int", "bar").getVariables().get(0).setInitializer("0"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + } + + @Test + public void registerWithNodeAndExistingDescendantsMode() { + String code = "class A { int f; void foo(int p) { return 'z'; }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + @Override + public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { + changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue)); + } + }; + cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.THIS_NODE_AND_EXISTING_DESCENDANTS); + + assertEquals(Arrays.asList(), changes); + + cu.getClassByName("A").get().setName("MyCoolClass"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN)); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean"), changes); + + cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean", + "Parameter.name changed from p to myParam"), changes); + + cu.getClassByName("MyCoolClass").get().addField("int", "bar").getVariables().get(0).setInitializer("0"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean", + "Parameter.name changed from p to myParam"), changes); + } + + @Test + public void registerWithSelfPropagatingMode() { + String code = "class A { int f; void foo(int p) { return 'z'; }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + @Override + public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { + changes.add(String.format("%s.%s changed from %s to %s", observedNode.getClass().getSimpleName(), property.name().toLowerCase(), oldValue, newValue)); + } + }; + cu.getClassByName("A").get().register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING); + + assertEquals(Arrays.asList(), changes); + + cu.getClassByName("A").get().setName("MyCoolClass"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass"), changes); + + cu.getClassByName("MyCoolClass").get().getFieldByName("f").get().getVariable(0).setType(new PrimitiveType(PrimitiveType.Primitive.BOOLEAN)); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean"), changes); + + cu.getClassByName("MyCoolClass").get().getMethodsByName("foo").get(0).getParameterByName("p").get().setName("myParam"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean", + "Parameter.name changed from p to myParam"), changes); + + cu.getClassByName("MyCoolClass").get() + .addField("int", "bar") + .getVariables().get(0).setInitializer("0"); + assertEquals(Arrays.asList("ClassOrInterfaceDeclaration.name changed from A to MyCoolClass", + "FieldDeclaration.maximum_common_type changed from int to boolean", + "VariableDeclarator.type changed from int to boolean", + "Parameter.name changed from p to myParam", + "VariableDeclarator.initializer changed from null to 0"), changes); + } + + @Test + public void deleteAParameterTriggerNotifications() { + String code = "class A { void foo(int p) { }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + + @Override + public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { + changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index); + } + }; + cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING); + + cu.getClassByName("A").get().getMethodsByName("foo").get(0).getParameter(0).remove(); + assertEquals(Arrays.asList("removing [int p] from index 0"), changes); + } + + @Test + public void deleteClassNameDoesNotTriggerNotifications() { + String code = "class A { void foo(int p) { }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + + @Override + public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { + changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index); + } + }; + cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING); + + // I cannot remove the name of a type + assertEquals(false, cu.getClassByName("A").get().getName().remove()); + assertEquals(Arrays.asList(), changes); + } + + @Test + public void deleteMethodBodyDoesTriggerNotifications() { + String code = "class A { void foo(int p) { }}"; + CompilationUnit cu = parse(code); + List<String> changes = new ArrayList<>(); + AstObserver observer = new AstObserverAdapter() { + + @Override + public void propertyChange(Node observedNode, ObservableProperty property, Object oldValue, Object newValue) { + changes.add("setting [" + property + "] to " + newValue); + } + + @Override + public void listChange(NodeList observedNode, ListChangeType type, int index, Node nodeAddedOrRemoved) { + changes.add("removing [" + nodeAddedOrRemoved + "] from index " + index); + } + }; + cu.register(observer, Node.ObserverRegistrationMode.SELF_PROPAGATING); + + assertEquals(true, cu.getClassByName("A").get().getMethodsByName("foo").get(0).getBody().get().remove()); + assertEquals(Arrays.asList("setting [BODY] to null"), changes); + } + + @Test + public void removeOrphanCommentPositiveCase() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A"); + Comment c = new LineComment("A comment"); + decl.addOrphanComment(c); + assertEquals(1, decl.getOrphanComments().size()); + assertTrue(decl == c.getParentNode().get()); + assertTrue(decl.removeOrphanComment(c)); + assertEquals(0, decl.getOrphanComments().size()); + assertFalse(c.getParentNode().isPresent()); + } + + @Test + public void removeOrphanCommentNegativeCase() { + ClassOrInterfaceDeclaration aClass = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), false, "A"); + FieldDeclaration aField = new FieldDeclaration(EnumSet.noneOf(Modifier.class), new VariableDeclarator(PrimitiveType.intType(), "f")); + aClass.getMembers().add(aField); + Comment c = new LineComment("A comment"); + aField.addOrphanComment(c); + // the comment is an orphan comment of the field, so trying to remove it on the class should not work + assertFalse(aClass.removeOrphanComment(c)); + assertEquals(1, aField.getOrphanComments().size()); + assertTrue(c.getParentNode().isPresent()); + } + + @Test + public void hasJavaDocCommentPositiveCaseWithSetJavaDocComment() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), + false, "Foo"); + decl.setJavadocComment("A comment"); + assertEquals(true, decl.hasJavaDocComment()); + } + + @Test + public void hasJavaDocCommentPositiveCaseWithSetComment() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), + false, "Foo"); + decl.setComment(new JavadocComment("A comment")); + assertEquals(true, decl.hasJavaDocComment()); + } + + @Test + public void hasJavaDocCommentNegativeCaseNoComment() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), + false, "Foo"); + assertEquals(false, decl.hasJavaDocComment()); + } + + @Test + public void hasJavaDocCommentNegativeCaseLineComment() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), + false, "Foo"); + decl.setComment(new LineComment("foo")); + assertEquals(false, decl.hasJavaDocComment()); + } + + @Test + public void hasJavaDocCommentNegativeCaseBlockComment() { + ClassOrInterfaceDeclaration decl = new ClassOrInterfaceDeclaration(EnumSet.noneOf(Modifier.class), + false, "Foo"); + decl.setComment(new BlockComment("foo")); + assertEquals(false, decl.hasJavaDocComment()); + } + + @Test + public void removeAllOnRequiredProperty() { + CompilationUnit cu = parse("class X{ void x(){}}"); + MethodDeclaration methodDeclaration = cu.getType(0).getMethods().get(0); + methodDeclaration.getName().removeForced(); + // Name is required, so to remove it the whole method is removed. + assertEquals(String.format("class X {%1$s}%1$s", EOL), cu.toString()); + } + + @Test + public void removingTheSecondOfAListOfIdenticalStatementsDoesNotMessUpTheParents() { + CompilationUnit unit = parse(String.format("public class Example {%1$s" + + " public static void example() {%1$s" + + " boolean swapped;%1$s" + + " swapped=false;%1$s" + + " swapped=false;%1$s" + + " }%1$s" + + "}%1$s", EOL)); + // remove the second swapped=false + Node target = unit.getChildNodes().get(0).getChildNodes().get(1).getChildNodes().get(2).getChildNodes().get(2); + target.remove(); + // This will throw an exception if the parents are bad. + System.out.println(unit.toString()); + } + + @Test + public void findCompilationUnit() { + CompilationUnit cu = parse("class X{int x;}"); + VariableDeclarator x = cu.getClassByName("X").get().getMember(0).asFieldDeclaration().getVariables().get(0); + assertEquals(cu, x.findCompilationUnit().get()); + } + + @Test + public void findParent() { + CompilationUnit cu = parse("class X{int x;}"); + SimpleName x = cu.getClassByName("X").get().getMember(0).asFieldDeclaration().getVariables().get(0).getName(); + assertEquals("int x;", x.findParent(FieldDeclaration.class).get().toString()); + } + + @Test + public void cantFindCompilationUnit() { + VariableDeclarator x = new VariableDeclarator(); + assertFalse(x.findCompilationUnit().isPresent()); + } + + @Test + public void genericWalk() { + Expression e = parseExpression("1+1"); + StringBuilder b = new StringBuilder(); + e.walk(n -> b.append(n.toString())); + assertEquals("1 + 111", b.toString()); + } + + @Test + public void classSpecificWalk() { + Expression e = parseExpression("1+1"); + StringBuilder b = new StringBuilder(); + e.walk(IntegerLiteralExpr.class, n -> b.append(n.toString())); + assertEquals("11", b.toString()); + } + + @Test + public void conditionalFindAll() { + Expression e = parseExpression("1+2+3"); + List<IntegerLiteralExpr> ints = e.findAll(IntegerLiteralExpr.class, n -> n.asInt() > 1); + assertEquals("[2, 3]", ints.toString()); + } + + @Test + public void typeOnlyFindAll() { + Expression e = parseExpression("1+2+3"); + List<IntegerLiteralExpr> ints = e.findAll(IntegerLiteralExpr.class); + assertEquals("[1, 2, 3]", ints.toString()); + } + + @Test + public void typeOnlyFindAllMatchesSubclasses() { + Expression e = parseExpression("1+2+3"); + List<Node> ints = e.findAll(Node.class); + assertEquals("[1 + 2 + 3, 1 + 2, 1, 2, 3]", ints.toString()); + } + + @Test + public void conditionalTypedFindFirst() { + Expression e = parseExpression("1+2+3"); + Optional<IntegerLiteralExpr> ints = e.findFirst(IntegerLiteralExpr.class, n -> n.asInt() > 1); + assertEquals("Optional[2]", ints.toString()); + } + + @Test + public void typeOnlyFindFirst() { + Expression e = parseExpression("1+2+3"); + Optional<IntegerLiteralExpr> ints = e.findFirst(IntegerLiteralExpr.class); + assertEquals("Optional[1]", ints.toString()); + } + + @Test + public void stream() { + Expression e = parseExpression("1+2+3"); + List<IntegerLiteralExpr> ints = e.stream() + .filter(n -> n instanceof IntegerLiteralExpr) + .map(IntegerLiteralExpr.class::cast) + .filter(i -> i.asInt() > 1) + .collect(Collectors.toList()); + assertEquals("[2, 3]", ints.toString()); + } +} |