@Override public void visit(final BlockStmt n, final A arg) { visitComment(n.getComment(), arg); if (n.getStmts() != null) { for (final Statement s : n.getStmts()) { s.accept(this, arg); } } }
@Override public Boolean visit(final BlockStmt n1, final Node arg) { final BlockStmt n2 = (BlockStmt) arg; if (!nodesEquals(n1.getStmts(), n2.getStmts())) { return Boolean.FALSE; } return Boolean.TRUE; }
// This method does the actual body generation: the body is forked for every children and only // added to the bodies list when the leaf is reached private static void generateTestBodies( RoundTripPathTreeNode node, BlockStmt body, List<BlockStmt> bodies, Map<String, Integer> usedVarNames) { final List<Statement> statements = body.getStmts(); final Transition transition = node.getTransition(); // This comment will be added to the first statement in this event check final LineComment comment = new LineComment(" " + node.getSignature()); boolean commentAdded = false; // Generate the condition reacher first if needed if (!transition.getCondition().isEmpty()) { final Statement conditionReacher = generateConditionReacher(transition.getCondition()); conditionReacher.setComment(comment); commentAdded = true; statements.add(conditionReacher); } // Next place the pre statements of the action checks final List<ActionCheck> checks = generateActionChecks(transition.getAction(), usedVarNames); for (ActionCheck check : checks) { final List<Statement> pre = check.getPre(); // Add the comment to the first pre statement, if any exist if (!commentAdded && !pre.isEmpty()) { pre.get(0).setComment(comment); commentAdded = true; } statements.addAll(pre); } // Now we add the actual event call final Statement eventStatement = eventAsStatement(transition.getEvent()); if (!commentAdded) { // If this is the first statement, add the comment now eventStatement.setComment(comment); } statements.add(eventStatement); // Next we check that the event caused the right state statements.add(generateStateCheck(transition.getTo().getName())); // Finally we check the action results using the post statements for (ActionCheck check : checks) { statements.add(check.getPost()); } // Generate the rest of the test case using the children final List<RoundTripPathTreeNode> children = node.getChildren(); if (children.isEmpty()) { // Reached leaf, test case is complete bodies.add(body); } else { // Generate the test statements for the next state transitions for (RoundTripPathTreeNode child : children) { // Clone the body and used variable names to ensure each test case has its own generateTestBodies( child, (BlockStmt) body.clone(), bodies, new HashMap<String, Integer>(usedVarNames)); } } }
// This parses the action as a list of statements and replaces variables by equivalent getters // called on a "machine" variable private static List<Statement> actionAsStatements(String action) { if (action.isEmpty()) { return Collections.emptyList(); } try { final BlockStmt block = JavaParser.parseBlock('{' + action + '}'); // Replace fields by getters block.accept(VariableToGetter.INSTANCE, null); return block.getStmts(); } catch (ParseException exception) { throw new RuntimeException(exception); } }