1 /* 2 * Copyright (C) 2007-2010 Jlio Vilmar Gesser. 3 * Copyright (C) 2011, 2013-2016 The JavaParser Team. 4 * 5 * This file is part of JavaParser. 6 * 7 * JavaParser can be used either under the terms of 8 * a) the GNU Lesser General Public License as published by 9 * the Free Software Foundation, either version 3 of the License, or 10 * (at your option) any later version. 11 * b) the terms of the Apache License 12 * 13 * You should have received a copy of both licenses in LICENCE.LGPL and 14 * LICENCE.APACHE. Please refer to those files for details. 15 * 16 * JavaParser is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU Lesser General Public License for more details. 20 */ 21 22 package com.github.javaparser.bdd.steps; 23 24 import com.github.javaparser.JavaParser; 25 import com.github.javaparser.ParseResult; 26 import com.github.javaparser.ast.CompilationUnit; 27 import com.github.javaparser.ast.Node; 28 import com.github.javaparser.ast.PackageDeclaration; 29 import com.github.javaparser.ast.body.*; 30 import com.github.javaparser.ast.expr.*; 31 import com.github.javaparser.ast.stmt.BlockStmt; 32 import com.github.javaparser.ast.stmt.ExpressionStmt; 33 import com.github.javaparser.ast.stmt.ReturnStmt; 34 import com.github.javaparser.ast.stmt.Statement; 35 import org.jbehave.core.annotations.Given; 36 import org.jbehave.core.annotations.Then; 37 import org.jbehave.core.annotations.When; 38 39 import java.util.List; 40 import java.util.Map; 41 42 import static com.github.javaparser.ParseStart.COMPILATION_UNIT; 43 import static com.github.javaparser.Providers.provider; 44 import static com.github.javaparser.bdd.steps.SharedSteps.getMemberByTypeAndPosition; 45 import static com.github.javaparser.bdd.steps.SharedSteps.getMethodByPositionAndClassPosition; 46 import static java.lang.String.format; 47 import static org.hamcrest.core.Is.is; 48 import static org.hamcrest.core.IsNull.notNullValue; 49 import static org.junit.Assert.*; 50 51 public class ParsingSteps { 52 53 private Map<String, Object> state; 54 55 public ParsingSteps(Map<String, Object> state) { 56 this.state = state; 57 } 58 59 private String sourceUnderTest; 60 61 /* 62 * Given steps 63 */ 64 65 @Given("the class:$classSrc") 66 public void givenTheClass(String classSrc) { 67 this.sourceUnderTest = classSrc.trim(); 68 } 69 70 71 /* 72 * When steps 73 */ 74 75 @When("I take the ArrayCreationExpr") 76 public void iTakeTheArrayCreationExpr() { 77 setSelectedNodeFromCompilationUnit(ArrayCreationExpr.class); 78 } 79 80 @When("I take the PackageDeclaration") 81 public void iTakeThePackageDeclaration() { 82 setSelectedNodeFromCompilationUnit(PackageDeclaration.class); 83 } 84 85 @When("I take the ObjectCreationExpr") 86 public void iTakeTheObjectCreationExpr() throws ClassNotFoundException { 87 setSelectedNodeFromCompilationUnit(ObjectCreationExpr.class); 88 } 89 90 /* 91 * Then steps 92 */ 93 94 @Then("constructor $constructorPosition in class $classPosition declaration as a String is \"$expectedString\"") 95 public void thenTheConstructorDeclarationAsAStringIs(int constructorPosition, int classPosition, String expectedString) { 96 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 97 ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1); 98 ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1); 99 assertThat(constructor.getDeclarationAsString(), is(expectedString)); 100 } 101 102 @Then("constructor $constructorPosition in class $classPosition declaration short form as a String is \"$expectedString\"") 103 public void thenConstructorInClassDeclarationShortFormAsAStringIs(int constructorPosition, int classPosition, String expectedString) { 104 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 105 ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1); 106 ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1); 107 assertThat(constructor.getDeclarationAsString(false, false), is(expectedString)); 108 } 109 110 @Then("method $methodPosition in class $classPosition declaration as a String is \"$expectedString\"") 111 public void thenMethod1InClass1DeclarationAsAStringIs(int methodPosition, int classPosition, String expectedString) { 112 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 113 ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1); 114 MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1); 115 assertThat(method.getDeclarationAsString(), is(expectedString)); 116 } 117 118 @Then("method $methodPosition in class $classPosition declaration as a String short form is \"$expectedString\"") 119 public void thenMethodInClassDeclarationAsAStringShortFormIs(int methodPosition, int classPosition, String expectedString) { 120 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 121 ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1); 122 MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1); 123 assertThat(method.getDeclarationAsString(false, false), is(expectedString)); 124 } 125 126 @Then("field $fieldPosition in class $classPosition contains annotation $annotationPosition value is \"$expectedValue\"") 127 public void thenFieldInClassContainsAnnotationValueIs(int fieldPosition, int classPosition, int annotationPosition, String expectedValue) { 128 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 129 130 TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1); 131 FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1, 132 FieldDeclaration.class); 133 AnnotationExpr annotationUnderTest = fieldUnderTest.getAnnotation(annotationPosition - 1); 134 assertThat(annotationUnderTest.getChildNodes().get(1).toString(), is(expectedValue)); 135 } 136 137 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is called $expectedName") 138 public void thenLambdaInClassIsCalled(int statementPosition, int methodPosition, int classPosition, String expectedName) { 139 Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition); 140 VariableDeclarationExpr expression = (VariableDeclarationExpr) ((ExpressionStmt) statement).getExpression(); 141 VariableDeclarator variableDeclarator = expression.getVariable(0); 142 assertThat(variableDeclarator.getNameAsString(), is(expectedName)); 143 } 144 145 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"") 146 public void thenLambdaInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition, 147 String expectedBody) { 148 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 149 assertThat(lambdaExpr.getBody().toString(), is(expectedBody)); 150 } 151 152 @Then("lambda in method call in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"") 153 public void thenLambdaInMethodCallInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition, 154 String expectedBody) { 155 ExpressionStmt statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt(); 156 VariableDeclarationExpr variableDeclarationExpr = statement.getExpression().asVariableDeclarationExpr(); 157 VariableDeclarator variableDeclarator = variableDeclarationExpr.getVariable(0); 158 MethodCallExpr methodCallExpr = (MethodCallExpr) variableDeclarator.getInitializer().orElse(null); 159 CastExpr castExpr = methodCallExpr.getArgument(0).asCastExpr(); 160 LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr(); 161 assertThat(lambdaExpr.getBody().toString(), is(expectedBody)); 162 } 163 164 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is null") 165 public void thenLambdaInStatementInMethodInClassBlockStatementIsNull(int statementPosition, int methodPosition, int classPosition) { 166 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 167 BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt(); 168 assertEquals(true, blockStmt.getStatements().isEmpty()); 169 } 170 171 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition has parameters with non-null type") 172 public void thenLambdaInStatementInMethodInClassHasParametersWithNonNullType(int statementPosition, int methodPosition, int classPosition) { 173 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 174 for (Parameter parameter : lambdaExpr.getParameters()) { 175 assertThat(parameter.getType(), is(notNullValue())); 176 } 177 } 178 179 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is \"$expectedBody\"") 180 public void thenLambdaInStatementInMethodInClassBlockStatement(int statementPosition, int methodPosition, int classPosition, 181 String expectedBody) { 182 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 183 BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt(); 184 Statement lambdaStmt = blockStmt.getStatement(0); 185 assertThat(lambdaStmt.toString(), is(expectedBody)); 186 } 187 188 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained body") 189 public void thenLambdaInStatementInMethodInClassIsParentOfContainedBody(int statementPosition, int methodPosition, int classPosition) { 190 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 191 Statement body = lambdaExpr.getBody(); 192 assertThat(body.getParentNode().get(), is(lambdaExpr)); 193 } 194 195 @Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained parameter") 196 public void thenLambdaInStatementInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) { 197 LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition); 198 Parameter parameter = lambdaExpr.getParameter(0); 199 assertThat(parameter.getParentNode().get(), is(lambdaExpr)); 200 } 201 202 @Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition scope is $expectedName") 203 public void thenMethodReferenceInStatementInMethodInClassIsScope(int statementPosition, int methodPosition, 204 int classPosition, String expectedName) { 205 ExpressionStmt statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt(); 206 assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size()); 207 MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get(); 208 assertThat(methodReferenceUnderTest.getScope().toString(), is(expectedName)); 209 } 210 211 @Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition identifier is $expectedName") 212 public void thenMethodReferenceInStatementInMethodInClassIdentifierIsCompareByAge(int statementPosition, int methodPosition, 213 int classPosition, String expectedName) { 214 Statement statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition); 215 assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size()); 216 MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get(); 217 assertThat(methodReferenceUnderTest.getIdentifier(), is(expectedName)); 218 } 219 220 @Then("method $methodPosition class $classPosition is a default method") 221 public void thenMethodClassIsADefaultMethod(int methodPosition, int classPosition) { 222 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 223 MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit, 224 methodPosition, classPosition); 225 assertThat(methodUnderTest.isDefault(), is(true)); 226 } 227 228 @Then("method $methodPosition class $classPosition is not a default method") 229 public void thenMethodClassIsNotADefaultMethod(int methodPosition, int classPosition) { 230 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 231 MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit, 232 methodPosition, classPosition); 233 assertThat(methodUnderTest.isDefault(), is(false)); 234 } 235 236 private Statement getStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) { 237 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 238 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 239 return method.getBody().get().getStatement(statementPosition - 1); 240 } 241 242 private LambdaExpr getLambdaExprInStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) { 243 Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition); 244 VariableDeclarationExpr expression = ((ExpressionStmt) statement).getExpression().asVariableDeclarationExpr(); 245 VariableDeclarator variableDeclarator = expression.getVariable(0); 246 return (LambdaExpr) variableDeclarator.getInitializer().orElse(null); 247 } 248 249 @Then("all nodes refer to their parent") 250 public void allNodesReferToTheirParent() { 251 assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu1"); 252 } 253 254 @Then("all nodes of the second compilation unit refer to their parent") 255 public void thenAllNodesOfTheSecondCompilationUnitReferToTheirParent() { 256 assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu2"); 257 } 258 259 private void assertAllNodesOfTheCompilationUnitHaveTheirParentSet(String stateKey) { 260 CompilationUnit compilationUnit = (CompilationUnit) state.get(stateKey); 261 ExistenceOfParentNodeVerifier parentVerifier = new ExistenceOfParentNodeVerifier(); 262 parentVerifier.verify(compilationUnit); 263 } 264 265 @Then("ThenExpr in the conditional expression of the statement $statementPosition in method $methodPosition in class $classPosition is LambdaExpr") 266 public void thenLambdaInConditionalExpressionInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) { 267 ReturnStmt returnStmt = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asReturnStmt(); 268 ConditionalExpr conditionalExpr = (ConditionalExpr) returnStmt.getExpression().orElse(null); 269 assertThat(conditionalExpr.getElseExpr().getClass().getName(), is(LambdaExpr.class.getName())); 270 } 271 272 @Then("the begin line is $line") 273 public void thenTheBeginLineIs(int line) { 274 Node node = (Node) state.get("selectedNode"); 275 assertEquals(line, node.getBegin().get().line); 276 } 277 278 @Then("the begin column is $column") 279 public void thenTheBeginColumnIs(int column) { 280 Node node = (Node) state.get("selectedNode"); 281 assertEquals(column, node.getBegin().get().column); 282 } 283 284 @Then("the end line is $line") 285 public void thenTheEndLineIs(int line) { 286 Node node = (Node) state.get("selectedNode"); 287 assertEquals(line, node.getEnd().get().line); 288 } 289 290 @Then("the end column is $column") 291 public void thenTheEndColumnIs(int column) { 292 Node node = (Node) state.get("selectedNode"); 293 assertEquals(column, node.getEnd().get().column); 294 } 295 296 @Then("no errors are reported") 297 public void thenNoErrorsAreReported() { 298 // this is present just for readability in the scenario specification 299 // if the code is not parsed then exceptions are thrown before reaching this step 300 } 301 302 @Then("the package name is $package") 303 public void thenThePackageNameIs(String expected) { 304 PackageDeclaration node = (PackageDeclaration) state.get("selectedNode"); 305 assertEquals(expected, node.getNameAsString()); 306 assertEquals(expected, node.getName().toString()); 307 } 308 309 @Then("the type's diamond operator flag should be $expectedValue") 310 public void thenTheUsesDiamondOperatorShouldBeBooleanAsString(boolean expectedValue) { 311 ObjectCreationExpr expr = (ObjectCreationExpr) state.get("selectedNode"); 312 assertEquals(expectedValue, expr.getType().isUsingDiamondOperator()); 313 } 314 315 @Then("the Java parser cannot parse it because of an error") 316 public void javaParserCannotParseBecauseOfLexicalErrors() { 317 ParseResult<CompilationUnit> result = new JavaParser().parse(COMPILATION_UNIT, provider(sourceUnderTest)); 318 if (result.isSuccessful()) { 319 fail("Lexical error expected"); 320 } 321 } 322 323 @Then("the assignExpr produced doesn't have a null target") 324 public void thenTheAssignExprProducedDoesntHaveANullTarget() { 325 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 326 ClassOrInterfaceDeclaration classDeclaration = compilationUnit.getType(0).asClassOrInterfaceDeclaration(); 327 ConstructorDeclaration ctor = classDeclaration.getMember(1).asConstructorDeclaration(); 328 ExpressionStmt assignStmt = ctor.getBody().getStatement(0).asExpressionStmt(); 329 AssignExpr assignExpr = assignStmt.getExpression().asAssignExpr(); 330 assertNotNull(assignExpr.getTarget()); 331 assertEquals(NameExpr.class, assignExpr.getTarget().getClass()); 332 assertEquals(assignExpr.getTarget().asNameExpr().getNameAsString(), "mString"); 333 } 334 335 private void setSelectedNodeFromCompilationUnit(Class<? extends Node> nodeType) { 336 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 337 List<? extends Node> nodes = compilationUnit.findAll(nodeType); 338 if (nodes.size() != 1) { 339 throw new RuntimeException(format("Exactly one %s expected", nodeType.getSimpleName())); 340 } 341 state.put("selectedNode", nodes.get(0)); 342 } 343 } 344