/* * Copyright (c) 2013, the Dart project authors. * * Licensed under the Eclipse Public License v1.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at * * http://www.eclipse.org/legal/epl-v10.html * * Unless required by applicable law or agreed to in writing, software distributed under the License * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express * or implied. See the License for the specific language governing permissions and limitations under * the License. */ package com.google.dart.java2dart.processor; import com.google.common.collect.ImmutableList; import com.google.common.collect.Lists; import com.google.dart.engine.ast.ClassDeclaration; import com.google.dart.engine.ast.CompilationUnit; import com.google.dart.engine.ast.Expression; import com.google.dart.engine.ast.MethodInvocation; import com.google.dart.engine.ast.SimpleIdentifier; import com.google.dart.engine.ast.Statement; import com.google.dart.engine.ast.TypeName; import com.google.dart.engine.ast.visitor.GeneralizingAstVisitor; import com.google.dart.engine.scanner.Keyword; import com.google.dart.java2dart.Context; import com.google.dart.java2dart.util.JavaUtils; import static com.google.dart.java2dart.util.AstFactory.blockFunctionBody; import static com.google.dart.java2dart.util.AstFactory.expressionStatement; import static com.google.dart.java2dart.util.AstFactory.extendsClause; import static com.google.dart.java2dart.util.AstFactory.formalParameterList; import static com.google.dart.java2dart.util.AstFactory.functionExpression; import static com.google.dart.java2dart.util.AstFactory.identifier; import static com.google.dart.java2dart.util.AstFactory.instanceCreationExpression; import static com.google.dart.java2dart.util.AstFactory.methodDeclaration; import static com.google.dart.java2dart.util.AstFactory.methodInvocation; import static com.google.dart.java2dart.util.AstFactory.propertyAccess; import static com.google.dart.java2dart.util.AstFactory.string; import static com.google.dart.java2dart.util.AstFactory.typeName; import static com.google.dart.java2dart.util.AstFactory.variableDeclaration; import static com.google.dart.java2dart.util.AstFactory.variableDeclarationList; import static com.google.dart.java2dart.util.AstFactory.variableDeclarationStatement; import org.eclipse.jdt.core.dom.IMethodBinding; import org.eclipse.jdt.core.dom.ITypeBinding; import org.eclipse.jdt.core.dom.Modifier; import java.util.Collections; import java.util.List; /** * {@link SemanticProcessor} for Java <code>Object</code>. */ public class JUnitSemanticProcessor extends SemanticProcessor { /** * @return the name of all "test" methods in the hierarchy. */ private static List<String> getTestMethodNames(org.eclipse.jdt.core.dom.ITypeBinding binding) { if (binding == null) { return ImmutableList.<String> of(); } List<String> testMethods = Lists.newArrayList(); for (org.eclipse.jdt.core.dom.IMethodBinding method : binding.getDeclaredMethods()) { String methodName = method.getName(); if (Modifier.isPublic(method.getModifiers()) && methodName.startsWith("test")) { testMethods.add(methodName); } } testMethods.addAll(getTestMethodNames(binding.getSuperclass())); return testMethods; } public JUnitSemanticProcessor(Context context) { super(context); } @Override public void process(CompilationUnit unit) { unit.accept(new GeneralizingAstVisitor<Void>() { @Override public Void visitClassDeclaration(ClassDeclaration node) { ITypeBinding typeBinding = context.getNodeTypeBinding(node); if (JavaUtils.isSubtype(typeBinding, "junit.framework.TestCase")) { // replace extends clause if (JavaUtils.isTypeNamed(typeBinding.getSuperclass(), "junit.framework.TestCase")) { node.setExtendsClause(extendsClause(typeName("JUnitTestCase"))); } // generate "dartSuite" if (!node.isAbstract()) { generateDartSuite(node); } } return super.visitClassDeclaration(node); } @Override public Void visitMethodInvocation(MethodInvocation node) { super.visitMethodInvocation(node); SimpleIdentifier nameNode = node.getMethodName(); String name = nameNode.getName(); List<Expression> args = node.getArgumentList().getArguments(); if (isJUnitAssertMethod(node)) { IMethodBinding binding = (IMethodBinding) context.getNodeBinding(node); if (JavaUtils.isTypeNamed(binding.getDeclaringClass(), "junit.framework.Assert")) { node.setTarget(identifier("JUnitTestCase")); } if (isMethodInClass2( node, "assertTrue(java.lang.String,boolean)", "junit.framework.Assert")) { node.setMethodName(identifier("assertTrueMsg")); } if (isMethodInClass2( node, "assertFalse(java.lang.String,boolean)", "junit.framework.Assert")) { node.setMethodName(identifier("assertFalseMsg")); } if (isMethodInClass2( node, "assertNull(java.lang.String,java.lang.Object)", "junit.framework.Assert")) { node.setMethodName(identifier("assertNullMsg")); } if (isMethodInClass2( node, "assertNotNull(java.lang.String,java.lang.Object)", "junit.framework.Assert")) { node.setMethodName(identifier("assertNotNullMsg")); } if (name.equals("assertEquals")) { if (args.size() == 3) { node.setMethodName(identifier("assertEqualsMsg")); } } if (name.equals("assertSame")) { if (args.size() == 3) { node.setMethodName(identifier("assertSameMsg")); } } } return null; } private void generateDartSuite(ClassDeclaration node) { ITypeBinding typeBinding = context.getNodeTypeBinding(node); TypeName suiteTypeName = typeName(node.getName()); SimpleIdentifier testInstanceIdentifier = identifier("__test"); Statement testStatementInstance = variableDeclarationStatement(variableDeclarationList( Keyword.FINAL, (TypeName) null, variableDeclaration( testInstanceIdentifier, instanceCreationExpression(Keyword.NEW, suiteTypeName)))); // prepare "test" invocations List<Statement> testInvocationStatements = Lists.newArrayList(); { List<String> testMethodNames = getTestMethodNames(typeBinding); Collections.sort(testMethodNames); for (String methodName : testMethodNames) { List<Statement> testStatements = Lists.newArrayList(); testStatements.add(testStatementInstance); testStatements.add(expressionStatement(methodInvocation( "runJUnitTest", testInstanceIdentifier, propertyAccess(testInstanceIdentifier, methodName)))); MethodInvocation testInvocation = methodInvocation( "_ut.test", string(methodName), functionExpression(formalParameterList(), blockFunctionBody(testStatements))); testInvocationStatements.add(expressionStatement(testInvocation)); } } // add "dartSuite" method MethodInvocation groupInvocation = methodInvocation( "_ut.group", string(node.getName().getName()), functionExpression(formalParameterList(), blockFunctionBody(testInvocationStatements))); node.getMembers().add( methodDeclaration( null, true, null, identifier("dartSuite"), formalParameterList(), blockFunctionBody(expressionStatement(groupInvocation)))); } private boolean isJUnitAssertMethod(MethodInvocation node) { return JavaUtils.isMethodInClass(context.getNodeBinding(node), "junit.framework.Assert"); } }); } }