All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.gwt.junit.rebind.JUnitTestCaseStubGenerator Maven / Gradle / Ivy

There is a newer version: 2.10.0
Show newest version
/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.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.apache.org/licenses/LICENSE-2.0
 * 
 * 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.gwt.junit.rebind;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JParameter;
import com.google.gwt.core.ext.typeinfo.NotFoundException;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * This class generates a stub class for classes that derive from GWTTestCase.
 * This stub class provides the necessary bridge between our Hosted or Hybrid
 * mode classes and the JUnit system.
 */
public class JUnitTestCaseStubGenerator extends Generator {

  /**
   * An interface for filtering out methods.
   */
  protected interface MethodFilter {
    boolean accept(JMethod method);
  }

  /**
   * Like JClassType.getMethod(String name) except:
   * 
   * 
  • it accepts a filter
  • *
  • it searches the inheritance hierarchy (includes superclasses)
  • * * For methods which are overridden, only the most derived implementations are * included. * * @param type the type to search (non-null) * @return the set of matching methods (non-null) */ protected static Map> getAllMethods(JClassType type, MethodFilter filter) { Map> methods = new HashMap>(); JClassType cls = type; while (cls != null) { JMethod[] clsDeclMethods = cls.getMethods(); // For every method, include it iff our filter accepts it // and we don't already have a matching method for (int i = 0, n = clsDeclMethods.length; i < n; ++i) { JMethod declMethod = clsDeclMethods[i]; if (!filter.accept(declMethod)) { continue; } List list = methods.get(declMethod.getName()); if (list == null) { list = new ArrayList(); methods.put(declMethod.getName(), list); list.add(declMethod); continue; } JParameter[] declParams = declMethod.getParameters(); for (int j = 0; j < list.size(); ++j) { JMethod method = list.get(j); JParameter[] parameters = method.getParameters(); if (!equals(declParams, parameters)) { list.add(declMethod); } } } cls = cls.getSuperclass(); } return methods; } /** * Returns true if the method is considered to be a valid JUnit test method. * The criteria are that the method's name begin with "test" and have public * access. The method may be static. You must choose to include or exclude * methods which have arguments. */ protected static boolean isJUnitTestMethod(JMethod method, boolean acceptArgs) { if (!method.getName().startsWith("test")) { return false; } if (!method.isPublic()) { return false; } return acceptArgs || method.getParameters().length == 0 && !acceptArgs; } /** * Returns true IFF the two sets of parameters are of the same lengths and * types. * * @param params1 must not be null * @param params2 must not be null */ private static boolean equals(JParameter[] params1, JParameter[] params2) { if (params1.length != params2.length) { return false; } for (int i = 0; i < params1.length; ++i) { if (params1[i].getType() != params2[i].getType()) { return false; } } return true; } /** * Returns the method names for the set of methods that are strictly JUnit * test methods (have no arguments). * * @param requestedClass */ private static String[] getTestMethodNames(JClassType requestedClass) { return getAllMethods(requestedClass, new MethodFilter() { public boolean accept(JMethod method) { return isJUnitTestMethod(method, false); } }).keySet().toArray(new String[] {}); } protected TreeLogger logger; private String packageName; private String qualifiedStubClassName; private JClassType requestedClass; private String simpleStubClassName; private SourceWriter sourceWriter; private TypeOracle typeOracle; /** * Create a new type that satisfies the rebind request. */ @Override public String generate(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { if (!init(logger, context, typeName)) { return qualifiedStubClassName; } writeSource(); sourceWriter.commit(logger); return qualifiedStubClassName; } protected JClassType getRequestedClass() { return requestedClass; } protected SourceWriter getSourceWriter() { return sourceWriter; } protected TypeOracle getTypeOracle() { return typeOracle; } @SuppressWarnings("unused") protected void writeSource() throws UnableToCompleteException { String[] testMethods = getTestMethodNames(requestedClass); writeDoRunTestMethod(testMethods, sourceWriter); } /** * Gets the name of the native stub class. */ private String getSimpleStubClassName(JClassType baseClass) { return "__" + baseClass.getSimpleSourceName() + "_unitTestImpl"; } private SourceWriter getSourceWriter(TreeLogger logger, GeneratorContext ctx, String packageName, String className, String superclassName) { PrintWriter printWriter = ctx.tryCreate(logger, packageName, className); if (printWriter == null) { return null; } ClassSourceFileComposerFactory composerFactory = new ClassSourceFileComposerFactory( packageName, className); composerFactory.setSuperclass(superclassName); return composerFactory.createSourceWriter(ctx, printWriter); } private boolean init(TreeLogger logger, GeneratorContext context, String typeName) throws UnableToCompleteException { this.logger = logger; typeOracle = context.getTypeOracle(); assert typeOracle != null; try { requestedClass = typeOracle.getType(typeName); } catch (NotFoundException e) { logger.log( TreeLogger.ERROR, "Could not find type '" + typeName + "'; please see the log, as this usually indicates a previous error ", e); throw new UnableToCompleteException(); } // Get the stub class name, and see if its source file exists. // simpleStubClassName = getSimpleStubClassName(requestedClass); packageName = requestedClass.getPackage().getName(); qualifiedStubClassName = packageName + "." + simpleStubClassName; sourceWriter = getSourceWriter(logger, context, packageName, simpleStubClassName, requestedClass.getQualifiedSourceName()); return sourceWriter != null; } private void writeDoRunTestMethod(String[] testMethodNames, SourceWriter sw) { sw.println(); sw.println("protected final void doRunTest(String name) throws Throwable {"); sw.indent(); for (int i = 0, n = testMethodNames.length; i < n; ++i) { String methodName = testMethodNames[i]; if (i > 0) { sw.print("else "); } sw.println("if (name.equals(\"" + methodName + "\")) {"); sw.indentln(methodName + "();"); sw.println("}"); } sw.outdent(); sw.println("}"); // finish doRunTest(); } }




    © 2015 - 2024 Weber Informatics LLC | Privacy Policy