blob: 2112aab34b87574d66199cefc6a0535b19a8688e [file] [log] [blame]
/*
* 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.steps;
import com.github.javaparser.JavaParser;
import com.github.javaparser.ParseResult;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Node;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.BlockStmt;
import com.github.javaparser.ast.stmt.ExpressionStmt;
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.stmt.Statement;
import org.jbehave.core.annotations.Given;
import org.jbehave.core.annotations.Then;
import org.jbehave.core.annotations.When;
import java.util.List;
import java.util.Map;
import static com.github.javaparser.ParseStart.COMPILATION_UNIT;
import static com.github.javaparser.Providers.provider;
import static com.github.javaparser.steps.SharedSteps.getMemberByTypeAndPosition;
import static com.github.javaparser.steps.SharedSteps.getMethodByPositionAndClassPosition;
import static java.lang.String.format;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.junit.jupiter.api.Assertions.*;
import static org.hamcrest.MatcherAssert.assertThat;
public class ParsingSteps {
private Map<String, Object> state;
public ParsingSteps(Map<String, Object> state) {
this.state = state;
}
private String sourceUnderTest;
/*
* Given steps
*/
@Given("the class:$classSrc")
public void givenTheClass(String classSrc) {
this.sourceUnderTest = classSrc.trim();
}
/*
* When steps
*/
@When("I take the ArrayCreationExpr")
public void iTakeTheArrayCreationExpr() {
setSelectedNodeFromCompilationUnit(ArrayCreationExpr.class);
}
@When("I take the PackageDeclaration")
public void iTakeThePackageDeclaration() {
setSelectedNodeFromCompilationUnit(PackageDeclaration.class);
}
@When("I take the ObjectCreationExpr")
public void iTakeTheObjectCreationExpr() throws ClassNotFoundException {
setSelectedNodeFromCompilationUnit(ObjectCreationExpr.class);
}
/*
* Then steps
*/
@Then("constructor $constructorPosition in class $classPosition declaration as a String is \"$expectedString\"")
public void thenTheConstructorDeclarationAsAStringIs(int constructorPosition, int classPosition, String expectedString) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1);
assertThat(constructor.getDeclarationAsString(), is(expectedString));
}
@Then("constructor $constructorPosition in class $classPosition declaration short form as a String is \"$expectedString\"")
public void thenConstructorInClassDeclarationShortFormAsAStringIs(int constructorPosition, int classPosition, String expectedString) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
ConstructorDeclaration constructor = (ConstructorDeclaration) clazz.getMember(constructorPosition - 1);
assertThat(constructor.getDeclarationAsString(false, false), is(expectedString));
}
@Then("method $methodPosition in class $classPosition declaration as a String is \"$expectedString\"")
public void thenMethod1InClass1DeclarationAsAStringIs(int methodPosition, int classPosition, String expectedString) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1);
assertThat(method.getDeclarationAsString(), is(expectedString));
}
@Then("method $methodPosition in class $classPosition declaration as a String short form is \"$expectedString\"")
public void thenMethodInClassDeclarationAsAStringShortFormIs(int methodPosition, int classPosition, String expectedString) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
ClassOrInterfaceDeclaration clazz = (ClassOrInterfaceDeclaration) compilationUnit.getType(classPosition - 1);
MethodDeclaration method = (MethodDeclaration) clazz.getMember(methodPosition - 1);
assertThat(method.getDeclarationAsString(false, false), is(expectedString));
}
@Then("field $fieldPosition in class $classPosition contains annotation $annotationPosition value is \"$expectedValue\"")
public void thenFieldInClassContainsAnnotationValueIs(int fieldPosition, int classPosition, int annotationPosition, String expectedValue) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
TypeDeclaration<?> classUnderTest = compilationUnit.getType(classPosition - 1);
FieldDeclaration fieldUnderTest = getMemberByTypeAndPosition(classUnderTest, fieldPosition - 1,
FieldDeclaration.class);
AnnotationExpr annotationUnderTest = fieldUnderTest.getAnnotation(annotationPosition - 1);
assertThat(annotationUnderTest.getChildNodes().get(1).toString(), is(expectedValue));
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is called $expectedName")
public void thenLambdaInClassIsCalled(int statementPosition, int methodPosition, int classPosition, String expectedName) {
Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
VariableDeclarationExpr expression = (VariableDeclarationExpr) ((ExpressionStmt) statement).getExpression();
VariableDeclarator variableDeclarator = expression.getVariable(0);
assertThat(variableDeclarator.getNameAsString(), is(expectedName));
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"")
public void thenLambdaInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition,
String expectedBody) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
assertThat(lambdaExpr.getBody().toString(), is(expectedBody));
}
@Then("lambda in method call in statement $statementPosition in method $methodPosition in class $classPosition body is \"$expectedBody\"")
public void thenLambdaInMethodCallInStatementInMethodInClassBody(int statementPosition, int methodPosition, int classPosition,
String expectedBody) {
ExpressionStmt statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt();
VariableDeclarationExpr variableDeclarationExpr = statement.getExpression().asVariableDeclarationExpr();
VariableDeclarator variableDeclarator = variableDeclarationExpr.getVariable(0);
MethodCallExpr methodCallExpr = (MethodCallExpr) variableDeclarator.getInitializer().orElse(null);
CastExpr castExpr = methodCallExpr.getArgument(0).asCastExpr();
LambdaExpr lambdaExpr = castExpr.getExpression().asLambdaExpr();
assertThat(lambdaExpr.getBody().toString(), is(expectedBody));
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is null")
public void thenLambdaInStatementInMethodInClassBlockStatementIsNull(int statementPosition, int methodPosition, int classPosition) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt();
assertEquals(true, blockStmt.getStatements().isEmpty());
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition has parameters with non-null type")
public void thenLambdaInStatementInMethodInClassHasParametersWithNonNullType(int statementPosition, int methodPosition, int classPosition) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
for (Parameter parameter : lambdaExpr.getParameters()) {
assertThat(parameter.getType(), is(notNullValue()));
}
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition block statement is \"$expectedBody\"")
public void thenLambdaInStatementInMethodInClassBlockStatement(int statementPosition, int methodPosition, int classPosition,
String expectedBody) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
BlockStmt blockStmt = lambdaExpr.getBody().asBlockStmt();
Statement lambdaStmt = blockStmt.getStatement(0);
assertThat(lambdaStmt.toString(), is(expectedBody));
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained body")
public void thenLambdaInStatementInMethodInClassIsParentOfContainedBody(int statementPosition, int methodPosition, int classPosition) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
Statement body = lambdaExpr.getBody();
assertThat(body.getParentNode().get(), is(lambdaExpr));
}
@Then("lambda in statement $statementPosition in method $methodPosition in class $classPosition is parent of contained parameter")
public void thenLambdaInStatementInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) {
LambdaExpr lambdaExpr = getLambdaExprInStatementInMethodInClass(statementPosition, methodPosition, classPosition);
Parameter parameter = lambdaExpr.getParameter(0);
assertThat(parameter.getParentNode().get(), is(lambdaExpr));
}
@Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition scope is $expectedName")
public void thenMethodReferenceInStatementInMethodInClassIsScope(int statementPosition, int methodPosition,
int classPosition, String expectedName) {
ExpressionStmt statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asExpressionStmt();
assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size());
MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get();
assertThat(methodReferenceUnderTest.getScope().toString(), is(expectedName));
}
@Then("method reference in statement $statementPosition in method $methodPosition in class $classPosition identifier is $expectedName")
public void thenMethodReferenceInStatementInMethodInClassIdentifierIsCompareByAge(int statementPosition, int methodPosition,
int classPosition, String expectedName) {
Statement statementUnderTest = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
assertEquals(1, statementUnderTest.findAll(MethodReferenceExpr.class).size());
MethodReferenceExpr methodReferenceUnderTest = statementUnderTest.findFirst(MethodReferenceExpr.class).get();
assertThat(methodReferenceUnderTest.getIdentifier(), is(expectedName));
}
@Then("method $methodPosition class $classPosition is a default method")
public void thenMethodClassIsADefaultMethod(int methodPosition, int classPosition) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit,
methodPosition, classPosition);
assertThat(methodUnderTest.isDefault(), is(true));
}
@Then("method $methodPosition class $classPosition is not a default method")
public void thenMethodClassIsNotADefaultMethod(int methodPosition, int classPosition) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
MethodDeclaration methodUnderTest = getMethodByPositionAndClassPosition(compilationUnit,
methodPosition, classPosition);
assertThat(methodUnderTest.isDefault(), is(false));
}
private Statement getStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition);
return method.getBody().get().getStatement(statementPosition - 1);
}
private LambdaExpr getLambdaExprInStatementInMethodInClass(int statementPosition, int methodPosition, int classPosition) {
Statement statement = getStatementInMethodInClass(statementPosition, methodPosition, classPosition);
VariableDeclarationExpr expression = ((ExpressionStmt) statement).getExpression().asVariableDeclarationExpr();
VariableDeclarator variableDeclarator = expression.getVariable(0);
return (LambdaExpr) variableDeclarator.getInitializer().orElse(null);
}
@Then("all nodes refer to their parent")
public void allNodesReferToTheirParent() {
assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu1");
}
@Then("all nodes of the second compilation unit refer to their parent")
public void thenAllNodesOfTheSecondCompilationUnitReferToTheirParent() {
assertAllNodesOfTheCompilationUnitHaveTheirParentSet("cu2");
}
private void assertAllNodesOfTheCompilationUnitHaveTheirParentSet(String stateKey) {
CompilationUnit compilationUnit = (CompilationUnit) state.get(stateKey);
ExistenceOfParentNodeVerifier parentVerifier = new ExistenceOfParentNodeVerifier();
parentVerifier.verify(compilationUnit);
}
@Then("ThenExpr in the conditional expression of the statement $statementPosition in method $methodPosition in class $classPosition is LambdaExpr")
public void thenLambdaInConditionalExpressionInMethodInClassIsParentOfContainedParameter(int statementPosition, int methodPosition, int classPosition) {
ReturnStmt returnStmt = getStatementInMethodInClass(statementPosition, methodPosition, classPosition).asReturnStmt();
ConditionalExpr conditionalExpr = (ConditionalExpr) returnStmt.getExpression().orElse(null);
assertThat(conditionalExpr.getElseExpr().getClass().getName(), is(LambdaExpr.class.getName()));
}
@Then("the begin line is $line")
public void thenTheBeginLineIs(int line) {
Node node = (Node) state.get("selectedNode");
assertEquals(line, node.getBegin().get().line);
}
@Then("the begin column is $column")
public void thenTheBeginColumnIs(int column) {
Node node = (Node) state.get("selectedNode");
assertEquals(column, node.getBegin().get().column);
}
@Then("the end line is $line")
public void thenTheEndLineIs(int line) {
Node node = (Node) state.get("selectedNode");
assertEquals(line, node.getEnd().get().line);
}
@Then("the end column is $column")
public void thenTheEndColumnIs(int column) {
Node node = (Node) state.get("selectedNode");
assertEquals(column, node.getEnd().get().column);
}
@Then("no errors are reported")
public void thenNoErrorsAreReported() {
// this is present just for readability in the scenario specification
// if the code is not parsed then exceptions are thrown before reaching this step
}
@Then("the package name is $package")
public void thenThePackageNameIs(String expected) {
PackageDeclaration node = (PackageDeclaration) state.get("selectedNode");
assertEquals(expected, node.getNameAsString());
assertEquals(expected, node.getName().toString());
}
@Then("the type's diamond operator flag should be $expectedValue")
public void thenTheUsesDiamondOperatorShouldBeBooleanAsString(boolean expectedValue) {
ObjectCreationExpr expr = (ObjectCreationExpr) state.get("selectedNode");
assertEquals(expectedValue, expr.getType().isUsingDiamondOperator());
}
@Then("the Java parser cannot parse it because of an error")
public void javaParserCannotParseBecauseOfLexicalErrors() {
ParseResult<CompilationUnit> result = new JavaParser().parse(COMPILATION_UNIT, provider(sourceUnderTest));
if (result.isSuccessful()) {
fail("Lexical error expected");
}
}
@Then("the assignExpr produced doesn't have a null target")
public void thenTheAssignExprProducedDoesntHaveANullTarget() {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
ClassOrInterfaceDeclaration classDeclaration = compilationUnit.getType(0).asClassOrInterfaceDeclaration();
ConstructorDeclaration ctor = classDeclaration.getMember(1).asConstructorDeclaration();
ExpressionStmt assignStmt = ctor.getBody().getStatement(0).asExpressionStmt();
AssignExpr assignExpr = assignStmt.getExpression().asAssignExpr();
assertNotNull(assignExpr.getTarget());
assertEquals(NameExpr.class, assignExpr.getTarget().getClass());
assertEquals(assignExpr.getTarget().asNameExpr().getNameAsString(), "mString");
}
private void setSelectedNodeFromCompilationUnit(Class<? extends Node> nodeType) {
CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1");
List<? extends Node> nodes = compilationUnit.findAll(nodeType);
if (nodes.size() != 1) {
throw new RuntimeException(format("Exactly one %s expected", nodeType.getSimpleName()));
}
state.put("selectedNode", nodes.get(0));
}
}