blob: 8967543614be54378c10b132b37e546d02fb1066 [file] [log] [blame]
/*
* Copyright 2009 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.dev.javac;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.TreeLogger.Type;
import com.google.gwt.core.ext.typeinfo.TypeOracle;
import com.google.gwt.dev.javac.testing.impl.MockJavaResource;
import com.google.gwt.dev.javac.testing.impl.StaticJavaResource;
import com.google.gwt.dev.resource.Resource;
import com.google.gwt.dev.util.UnitTestTreeLogger;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import junit.framework.TestCase;
import java.util.Set;
/**
* A base type for testing the code checkers.
*/
public abstract class CheckerTestCase extends TestCase {
/**
* Pass represents passes to be run by the checker test cases.
*/
public interface Pass {
/**
* Run the pass. Returns true if pass completes successfully.
*/
boolean run(TreeLogger logger, MockJavaResource buggyResource, MockJavaResource extraResource);
boolean classAvailable(String className);
String getTopErrorMessage(Type logLevel, MockJavaResource resource);
}
/**
* A warning or error message.
*/
protected static class Message {
private int line;
private Type logLevel;
private String message;
private Message(int line, Type logLevel, String message) {
this.line = line;
this.logLevel = logLevel;
this.message = message;
}
}
/**
* Provide a pass to be checked by default runs only passes required to build TypeOracle.
*/
protected Pass providePass() {
return new Pass() {
private TypeOracle oracle = null;
@Override
public boolean run(TreeLogger logger, MockJavaResource buggyResource,
MockJavaResource extraResource) {
Set<Resource> resources = Sets.newHashSet();
addLongCheckingCups(resources);
Set<GeneratedUnit> generatedUnits =
CompilationStateTestBase.getGeneratedUnits(buggyResource);
if (extraResource != null) {
generatedUnits.addAll(CompilationStateTestBase.getGeneratedUnits(extraResource));
}
CompilationState state = TypeOracleTestingUtils.buildCompilationStateWith(logger,
resources, generatedUnits);
oracle = state.getTypeOracle();
return !state.hasErrors();
}
@Override
public boolean classAvailable(String className) {
return oracle.findType(className) != null;
}
@Override
public String getTopErrorMessage(Type logLevel, MockJavaResource resource) {
return (logLevel == Type.WARN ? "Warnings" : "Errors") +
" in '" + resource.getLocation() + "'";
}
};
}
protected Message warning(int line, String message) {
return new Message(line, Type.WARN, message);
}
protected Message error(int line, String message) {
return new Message(line, Type.ERROR, message);
}
protected void shouldGenerate(MockJavaResource buggyCode, MockJavaResource extraCode,
Type logLevel, Message... messages) {
UnitTestTreeLogger.Builder b = new UnitTestTreeLogger.Builder();
b.setLowestLogLevel(logLevel);
Pass pass = providePass();
String topLevelMessage = pass.getTopErrorMessage(logLevel, buggyCode);
if (messages.length != 0 && topLevelMessage != null) {
b.expect(logLevel, topLevelMessage, null);
}
for (Message message : messages) {
final String fullMessage = "Line " + message.line + ": " + message.message;
b.expect(message.logLevel, fullMessage, null);
}
UnitTestTreeLogger logger = b.createLogger();
boolean result = pass.run(logger, buggyCode, extraCode);
logger.assertCorrectLogEntries();
String className = buggyCode.getTypeName();
if (messages.length != 0 && logLevel == TreeLogger.ERROR) {
assertFalse("Compilation unit " + className + " not removed" +
" but should have been removed.",
pass.classAvailable(className));
} else {
assertTrue("Compilation unit " + className + " was removed but shouldnt have.",
pass.classAvailable(className));
}
boolean expectingErrors = messages.length != 0 && logLevel == Type.ERROR;
assertEquals(!expectingErrors, result);
}
protected void shouldGenerateError(MockJavaResource buggyCode, MockJavaResource extraCode,
int line, String message) {
shouldGenerate(buggyCode, extraCode, TreeLogger.ERROR, error(line, message));
}
protected void shouldGenerateError(MockJavaResource buggyCode, int line, String message) {
shouldGenerateError(buggyCode, null, line, message);
}
protected void shouldGenerateNoError(MockJavaResource code) {
shouldGenerateNoError(code, null);
}
protected void shouldGenerateNoError(MockJavaResource code, MockJavaResource extraCode) {
shouldGenerate(code, extraCode, TreeLogger.ERROR);
}
protected void shouldGenerateNoWarning(MockJavaResource code) {
shouldGenerateNoWarning(code, null);
}
protected void shouldGenerateNoWarning(MockJavaResource code, MockJavaResource extraCode) {
shouldGenerate(code, extraCode, TreeLogger.WARN);
}
protected void shouldGenerateWarning(MockJavaResource buggyCode,
MockJavaResource extraCode, int line, String message) {
shouldGenerate(buggyCode, extraCode, TreeLogger.WARN, warning(line, message));
}
protected void shouldGenerateWarning(MockJavaResource buggyCode, int line,
String message) {
shouldGenerateWarning(buggyCode, null, line, message);
}
protected void shouldGenerateWarnings(MockJavaResource buggyCode, Message... messages) {
shouldGenerateWarnings(buggyCode, null, messages);
}
protected void shouldGenerateWarnings(MockJavaResource buggyCode, MockJavaResource extraCode,
Message... messages) {
shouldGenerate(buggyCode, extraCode, TreeLogger.WARN, messages);
}
private void addLongCheckingCups(Set<Resource> resources) {
String code = Joiner.on('\n').join(
"package com.google.gwt.core.client;",
"public @interface UnsafeNativeLong {",
"}");
resources.add(new StaticJavaResource(
"com.google.gwt.core.client.UnsafeNativeLong", code.toString()));
}
}