blob: a390b0823c575b5e014735e2afa9cb3a57f3f97e [file] [log] [blame]
/*
* 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.tools.apichecker;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JAbstractMethod;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.CompilationUnit;
import com.google.gwt.dev.javac.JdtCompiler;
import com.google.gwt.dev.javac.TypeOracleMediator;
import com.google.gwt.dev.util.log.AbstractTreeLogger;
import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
import com.google.gwt.tools.apichecker.ApiCompatibilityTest.StaticCompilationUnit;
import junit.framework.TestCase;
import java.util.HashSet;
import java.util.Set;
/**
* Test ApiContainer.
*/
public class ApiContainerTest extends TestCase {
@SuppressWarnings("unused")
class TestA {
public TestA(String args) {
}
protected TestA(TestA a) {
}
public String valueOf(Object o) {
return "a";
}
public String valueOf(String s) {
return "";
}
}
class TestB extends TestA {
public TestB(TestA a) {
super(a);
}
public void main(String args[]) {
TestA x1 = new TestA("test");
x1.valueOf("ab");
TestB x2 = new TestB(x1);
new TestB(x2);
}
}
static StaticCompilationUnit cuApiClass = new StaticCompilationUnit(
"test.apicontainer.ApiClass", getSourceForApiClass());
static StaticCompilationUnit cuNonApiClass = new StaticCompilationUnit(
"test.apicontainer.NonApiClass", getSourceForNonApiClass());
static StaticCompilationUnit cuNonApiPackage = new StaticCompilationUnit(
"test.nonapipackage.TestClass", getSourceForTestClass());
static StaticCompilationUnit cuObject = new StaticCompilationUnit(
"java.lang.Object", getSourceForObject());
static StaticCompilationUnit cuNewPackage = new StaticCompilationUnit(
"java.newpackage.Test", getSourceForTest());
private static JAbstractMethod getMethodByName(String name, ApiClass apiClass) {
return (apiClass.getApiMethodsByName(name, ApiClass.MethodType.METHOD).toArray(
new ApiAbstractMethod[0])[0]).getMethodObject();
}
private static char[] getSourceForApiClass() {
StringBuffer sb = new StringBuffer();
sb.append("package test.apicontainer;\n");
sb.append("public class ApiClass extends NonApiClass {\n");
sb.append("\tpublic void apiMethod() { };\n");
sb.append("\tpublic java.lang.Object checkParametersAndReturnTypes(ApiClass a) { return this; };\n");
sb.append("};\n");
return sb.toString().toCharArray();
}
private static char[] getSourceForNonApiClass() {
StringBuffer sb = new StringBuffer();
sb.append("package test.apicontainer;\n");
sb.append("class NonApiClass extends java.lang.Object {\n");
sb.append("\tpublic void methodInNonApiClass(java.lang.Object a) { };\n");
sb.append("\tpublic int fieldInNonApiClass = 3;\n");
sb.append("\tprotected class ApiClassInNonApiClass {\n");
sb.append("\tprotected ApiClassInNonApiClass() { }\n");
sb.append("\t}\n");
sb.append("\tprotected final class AnotherApiClassInNonApiClass {\n");
sb.append("\tprivate AnotherApiClassInNonApiClass() { }\n");
sb.append("\t}\n");
sb.append("}\n");
return sb.toString().toCharArray();
}
private static char[] getSourceForObject() {
StringBuffer sb = new StringBuffer();
sb.append("package java.lang;\n");
sb.append("public class Object {\n");
sb.append("\tpublic void apiMethod() { }\n");
sb.append("\tprivate void internalMethod() { }\n");
sb.append("\tprotected native long protectedMethod();\n");
sb.append("\tpublic int apiField = 0;\n");
sb.append("\tprivate int internalField = 0;\n");
sb.append("\tprotected int protectedField=2;\n");
sb.append("}\n");
return sb.toString().toCharArray();
}
private static char[] getSourceForTest() {
StringBuffer sb = new StringBuffer();
sb.append("package java.newpackage;\n");
sb.append("public class Test { }\n");
return sb.toString().toCharArray();
}
private static char[] getSourceForTestClass() {
StringBuffer sb = new StringBuffer();
sb.append("package test.nonapipackage;\n");
sb.append("class TestClass extends java.lang.Object {\n");
sb.append("\tpublic void method() { }\n");
sb.append("}\n");
return sb.toString().toCharArray();
}
ApiContainer api1 = null;
// TODO (amitmanjhi): Try using UnitTestTreeLogger to capture log messages
public TypeOracle getNewTypeOracleWithCompilationUnitsAdded()
throws UnableToCompleteException {
AbstractTreeLogger logger = new PrintWriterTreeLogger();
logger.setMaxDetail(TreeLogger.ERROR);
// Build onto an empty type oracle.
TypeOracleMediator mediator = new TypeOracleMediator();
Set<CompilationUnit> units = new HashSet<CompilationUnit>();
units.add(cuObject);
units.add(cuNonApiClass);
units.add(cuApiClass);
units.add(cuNonApiPackage);
units.add(cuNewPackage);
JdtCompiler.compile(units);
mediator.refresh(logger, units);
return mediator.getTypeOracle();
}
/**
* Class hierarchy. public java.lang.Object -- test.apicontainer.NonApiClass
* (encloses ApiClassInNonApiClass and AnotherApiClassInNonApiClass) -- public
* test.apicontainer.ApiClass -- test.nonapipackage.TestClass
*/
@Override
public void setUp() {
AbstractTreeLogger logger1 = new PrintWriterTreeLogger();
logger1.setMaxDetail(TreeLogger.ERROR);
try {
api1 = new ApiContainer("ApiContainerTest", logger1,
getNewTypeOracleWithCompilationUnitsAdded());
} catch (Exception ex) {
// JSNI checks are active.
assertEquals("jsni checks are probably active", "failed");
}
}
/**
* Check if apiClasses are determined correctly. Check if inner classes are
* classified correctly as api classes.
*/
public void testApiClass() {
ApiPackage package1 = api1.getApiPackage("java.lang");
ApiPackage package2 = api1.getApiPackage("test.apicontainer");
assertNotNull(package1);
assertNotNull(package2);
assertNull(package2.getApiClass("test.apicontainer.NonApiClass"));
assertNotNull(package1.getApiClass("java.lang.Object"));
assertNotNull(package2.getApiClass("test.apicontainer.ApiClass"));
assertNotNull(package2.getApiClass("test.apicontainer.NonApiClass.ApiClassInNonApiClass"));
assertNotNull(package2.getApiClass("test.apicontainer.NonApiClass.AnotherApiClassInNonApiClass"));
assertEquals(1, package1.getApiClassNames().size());
assertEquals(3, package2.getApiClassNames().size());
}
/**
* Since constructors and methods use the same code, check methods in most
* cases. Also need to check apiFields.
*
* For methods, check if: (a) inherited methods are identified correctly as
* apiMethods, (b) method overloading is done correctly
*
*/
public void testApiMembers() {
ApiClass object = api1.getApiPackage("java.lang").getApiClass(
"java.lang.Object");
ApiClass apiClass = api1.getApiPackage("test.apicontainer").getApiClass(
"test.apicontainer.ApiClass");
ApiClass innerClass = api1.getApiPackage("test.apicontainer").getApiClass(
"test.apicontainer.NonApiClass.ApiClassInNonApiClass");
// constructors
assertEquals(1, innerClass.getApiMemberNames(
ApiClass.MethodType.CONSTRUCTOR).size());
// fields
assertEquals(2, object.getApiFieldNames().size());
assertEquals(3, apiClass.getApiFieldNames().size());
// methods
assertEquals(2, object.getApiMemberNames(ApiClass.MethodType.METHOD).size());
assertEquals(4,
apiClass.getApiMemberNames(ApiClass.MethodType.METHOD).size());
// the method definition lowest in the class hierarchy is kept
assertNotSame(getMethodByName("apiMethod0", apiClass), getMethodByName(
"apiMethod0", object));
assertEquals(getMethodByName("protectedMethod0", apiClass),
getMethodByName("protectedMethod0", object));
assertNotNull(getMethodByName("methodInNonApiClass1", apiClass));
}
/**
* Test if apiPackages are identified correctly.
*/
public void testApiPackages() {
assertNotNull(api1.getApiPackage("java.lang"));
assertNotNull(api1.getApiPackage("test.apicontainer"));
assertEquals(3, api1.getApiPackageNames().size());
}
}