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.ast.CompilationUnit; 26 import com.github.javaparser.ast.Modifier; 27 import com.github.javaparser.ast.NodeList; 28 import com.github.javaparser.ast.PackageDeclaration; 29 import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration; 30 import com.github.javaparser.ast.body.MethodDeclaration; 31 import com.github.javaparser.ast.body.Parameter; 32 import com.github.javaparser.ast.body.TypeDeclaration; 33 import com.github.javaparser.ast.expr.*; 34 import com.github.javaparser.ast.stmt.BlockStmt; 35 import com.github.javaparser.ast.stmt.Statement; 36 import com.github.javaparser.ast.stmt.TryStmt; 37 import com.github.javaparser.ast.type.ClassOrInterfaceType; 38 import com.github.javaparser.ast.type.VoidType; 39 import com.github.javaparser.ast.visitor.VoidVisitorAdapter; 40 import org.jbehave.core.annotations.Alias; 41 import org.jbehave.core.annotations.Given; 42 import org.jbehave.core.annotations.Then; 43 import org.jbehave.core.annotations.When; 44 45 import java.util.EnumSet; 46 import java.util.Map; 47 48 import static com.github.javaparser.JavaParser.parseClassOrInterfaceType; 49 import static com.github.javaparser.JavaParser.parseName; 50 import static com.github.javaparser.ast.NodeList.nodeList; 51 import static com.github.javaparser.ast.type.PrimitiveType.*; 52 import static com.github.javaparser.bdd.steps.SharedSteps.getMethodByPositionAndClassPosition; 53 import static org.hamcrest.CoreMatchers.is; 54 import static org.junit.Assert.assertNotEquals; 55 import static org.junit.Assert.assertThat; 56 57 public class ManipulationSteps { 58 59 /* Fields used to maintain step state within this step class */ 60 private BlockStmt blockStmt; 61 private Statement statement; 62 private TryStmt tryStmt; 63 private NodeList<Expression> variableDeclarationExprList; 64 private ChangeMethodNameToUpperCaseVisitor changeMethodNameToUpperCaseVisitor; 65 private AddNewIntParameterCalledValueVisitor addNewIntParameterCalledValueVisitor; 66 67 /* Map that maintains shares state across step classes. If manipulating the objects in the map you must update the state */ 68 private Map<String, Object> state; 69 70 public ManipulationSteps(Map<String, Object> state) { 71 this.state = state; 72 } 73 74 @Given("a BlockStmt") 75 public void givenABlockStatement() { 76 blockStmt = new BlockStmt(); 77 } 78 79 @Given("a Statement") 80 public void givenAStatement() { 81 statement = null; 82 } 83 84 @Given("a TryStmt") 85 public void givenATryStmt() { 86 tryStmt = new TryStmt(); 87 } 88 89 @Given("a List of VariableDeclarations") 90 public void givenAListOfVariableDeclarations() { 91 variableDeclarationExprList = new NodeList<>(); 92 variableDeclarationExprList.add(new VariableDeclarationExpr()); 93 variableDeclarationExprList.add(new VariableDeclarationExpr()); 94 } 95 96 @Given("a ChangeNameToUpperCaseVisitor") 97 public void givenAChangeNameToUpperCaseVisitor() { 98 changeMethodNameToUpperCaseVisitor = new ChangeMethodNameToUpperCaseVisitor(); 99 } 100 101 @Given("a AddNewIntParameterCalledValueVisitor") 102 public void givenAAddNewParameterCalledValueVisitor() { 103 addNewIntParameterCalledValueVisitor = new AddNewIntParameterCalledValueVisitor(); 104 } 105 106 @When("is the String \"$value\" is parsed by the JavaParser using parseBlock") 107 public void whenIsTheStringIsParsedByTheJavaParser(String value) { 108 blockStmt = JavaParser.parseBlock(value); 109 } 110 111 @When("is the String \"$value\" is parsed by the JavaParser using parseStatement") 112 public void whenIsTheStringIsParsedByTheJavaParserUsingParseStatement(String value) { 113 statement = JavaParser.parseStatement(value); 114 } 115 116 @When("the List of VariableDeclarations are set as the resources on TryStmt") 117 public void whenTheListOfVariableDeclarationsAreSetAsTheResourcesOnTryStmt() { 118 tryStmt.setResources(variableDeclarationExprList); 119 } 120 121 @When("empty list is set as the resources on TryStmt") 122 public void whenNullIsSetAsTheResourcesOnTryStmt() { 123 tryStmt.setResources(new NodeList<>()); 124 } 125 126 @When("the package declaration is set to \"$packageName\"") 127 public void whenThePackageDeclarationIsSetTo(String packageName) { 128 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 129 compilationUnit.setPackageDeclaration(new PackageDeclaration(parseName(packageName))); 130 state.put("cu1", compilationUnit); 131 } 132 133 @When("a public class called \"$className\" is added to the CompilationUnit") 134 public void whenAClassCalledIsAddedToTheCompilationUnit(String className) { 135 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 136 TypeDeclaration<?> type = new ClassOrInterfaceDeclaration(EnumSet.of(Modifier.PUBLIC), false, "CreateClass"); 137 compilationUnit.setTypes(nodeList(type)); 138 state.put("cu1", compilationUnit); 139 } 140 141 @When("a public static method called \"$methodName\" returning void is added to class $position in the compilation unit") 142 public void whenAStaticMethodCalledReturningIsAddedToClassInTheCompilationUnit(String methodName, int position) { 143 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 144 TypeDeclaration<?> type = compilationUnit.getType(position - 1); 145 EnumSet<Modifier> modifiers = EnumSet.of(Modifier.PUBLIC); 146 MethodDeclaration method = new MethodDeclaration(modifiers, new VoidType(), methodName); 147 modifiers.add(Modifier.STATIC); 148 method.setModifiers(modifiers); 149 type.addMember(method); 150 state.put("cu1", compilationUnit); 151 } 152 153 @When("$typeName varargs called \"$parameterName\" are added to method $methodPosition in class $classPosition") 154 public void whenVarargsCalledAreAddedToMethodInClass(String typeName, String parameterName, int methodPosition, int classPosition) { 155 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 156 getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition) 157 .addAndGetParameter(typeName, parameterName) 158 .setVarArgs(true); 159 } 160 161 @When("a BlockStmt is added to method $methodPosition in class $classPosition") 162 public void whenABlockStmtIsAddedToMethodInClass(int methodPosition, int classPosition) { 163 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 164 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 165 method.setBody(new BlockStmt()); 166 } 167 168 @When("$className.$fieldName.$methodName(\"$stringValue\"); is added to the body of method $methodPosition in class $classPosition") 169 public void whenHelloWorldIsAddedToTheBodyOfMethodInClass(String className, String fieldName, String methodName, String stringValue, 170 int methodPosition, int classPosition) { 171 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 172 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 173 NameExpr clazz = new NameExpr(className); 174 FieldAccessExpr field = new FieldAccessExpr(clazz, fieldName); 175 MethodCallExpr call = new MethodCallExpr(field, methodName); 176 call.addArgument(new StringLiteralExpr(stringValue)); 177 method.getBody().get().addStatement(call); 178 } 179 180 @When("method $methodPosition in class $classPosition has it's name converted to uppercase") 181 public void whenMethodInClassHasItsNameConvertedToUppercase(int methodPosition, int classPosition) { 182 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 183 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 184 method.setName(method.getNameAsString().toUpperCase()); 185 } 186 187 @When("method $methodPosition in class $classPosition has an int parameter called \"$paramName\" added") 188 public void whenMethodInClassHasAnIntArgumentCalledAdded(int methodPosition, int classPosition, String paramName) { 189 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 190 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 191 method.addParameter(intType(), paramName); 192 } 193 194 @When("the compilation unit is cloned") 195 public void whenTheCompilationUnitIsCloned() throws CloneNotSupportedException { 196 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 197 state.put("cu1", compilationUnit.clone()); 198 } 199 200 @When("the ChangeNameToUpperCaseVisitor visits to compilation unit") 201 public void whenTheVisitorVisitsToCompilationUnit() { 202 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 203 changeMethodNameToUpperCaseVisitor.visit(compilationUnit, null); 204 state.put("cu1", compilationUnit); 205 } 206 207 @When("the AddNewIntParameterCalledValueVisitor visits to compilation unit") 208 public void whenTheAddNewParameterCalledValueVisitorVisitsToCompilationUnit() { 209 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 210 addNewIntParameterCalledValueVisitor.visit(compilationUnit, null); 211 state.put("cu1", compilationUnit); 212 } 213 214 @Then("is not equal to null") 215 public void thenIsNotEqualToNull() { 216 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 217 assertNotEquals(compilationUnit, null); 218 } 219 220 @Then("is not equal to $value") 221 public void thenIsNotEqualTo(String value) { 222 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 223 assertNotEquals(compilationUnit, value); 224 } 225 226 @Then("Statement $position in BlockStmt toString is \"$expectedContent\"") 227 public void thenTheBlockStmtContentIs(int position, String expectedContent) { 228 Statement statementUnderTest = blockStmt.getStatement(position - 1); 229 assertThat(statementUnderTest.toString(), is(expectedContent)); 230 } 231 232 @Then("Statement toString is \"$expectedContent\"") 233 public void thenStatementToStringIsxXy(String expectedContent) { 234 assertThat(statement.toString(), is(expectedContent)); 235 } 236 237 @Then("all the VariableDeclarations parent is the TryStmt") 238 public void thenAllTheVariableDeclarationsParentIsTheTryStmt() { 239 variableDeclarationExprList.forEach(expr -> assertThat(expr.getParentNode().get(), is(tryStmt))); 240 } 241 242 @Then("the TryStmt has no child nodes") 243 public void thenTheTryStmtHasNotChildNodes() { 244 assertThat(tryStmt.getChildNodes().size(), is(0)); 245 } 246 247 @Then("method $methodPosition in class $classPosition has the name \"$expectedName\"") 248 public void thenMethodInClassHasTheName(int methodPosition, int classPosition, String expectedName) { 249 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 250 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 251 assertThat(method.getNameAsString(), is(expectedName)); 252 } 253 254 @Then("method $methodPosition in class $classPosition has $expectedCount parameters") 255 @Alias("method $methodPosition in class $classPosition has $expectedCount parameter") 256 public void thenMethodInClassHasArguments(int methodPosition, int classPosition, int expectedCount) { 257 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 258 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 259 260 assertThat(method.getParameters().size(), is(expectedCount)); 261 } 262 263 @Then("method $methodPosition in class $classPosition parameter $parameterPosition is type int called \"$expectedName\"") 264 public void thenMethodInClassParameterIsTypeIntCalled(int methodPosition, int classPosition, int parameterPosition, String expectedName) { 265 CompilationUnit compilationUnit = (CompilationUnit) state.get("cu1"); 266 MethodDeclaration method = getMethodByPositionAndClassPosition(compilationUnit, methodPosition, classPosition); 267 Parameter parameter = method.getParameter(parameterPosition - 1); 268 assertThat(parameter.getType(), is(intType())); 269 assertThat(parameter.getNameAsString(), is(expectedName)); 270 } 271 272 private static class ChangeMethodNameToUpperCaseVisitor extends VoidVisitorAdapter<Void> { 273 @Override 274 public void visit(MethodDeclaration n, Void arg) { 275 n.setName(n.getNameAsString().toUpperCase()); 276 } 277 } 278 279 private static class AddNewIntParameterCalledValueVisitor extends VoidVisitorAdapter<Void> { 280 @Override 281 public void visit(MethodDeclaration n, Void arg) { 282 n.addParameter(intType(), "value"); 283 } 284 } 285 } 286 287