Home | History | Annotate | Download | only in steps
      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