blob: a6c3ec7dd56d6621ed53327cde79dd524f84f63d [file] [log] [blame]
/*
* Copyright 2011 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.web.bindery.requestfactory.apt;
import com.google.gwt.dev.util.Util;
import com.google.web.bindery.requestfactory.gwt.client.RequestFactoryPolymorphicTest;
import com.google.web.bindery.requestfactory.shared.LoggingRequest;
import com.google.web.bindery.requestfactory.shared.SimpleRequestFactory;
import com.google.web.bindery.requestfactory.shared.TestRequestFactory;
import com.google.web.bindery.requestfactory.shared.impl.FindRequest;
import junit.framework.TestCase;
import java.io.File;
import java.io.IOException;
import java.io.StringWriter;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.TreeSet;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
import javax.tools.JavaCompiler.CompilationTask;
import javax.tools.JavaFileManager;
import javax.tools.JavaFileObject;
import javax.tools.SimpleJavaFileObject;
import javax.tools.ToolProvider;
/**
* Integration test of {@link RfValidator} using the Java6 tools API to invoke
* the Java compiler. This test requires that the gwt-user source is available
* on the classpath.
*/
public class RfValidatorTest extends TestCase {
/**
* Provides access to a source file from the classpath.
*/
private static class UriJavaFileObject extends SimpleJavaFileObject {
public static UriJavaFileObject create(Class<?> toLoad) {
try {
String path = toLoad.getName().replace('.', '/') + ".java";
/*
* SimpleJavaFileObject does not like the URI's created from jar URLs
* since their path does not start with a leading forward-slash. The
* choice of "classpath" as the scheme is arbitrary and meaningless.
*/
URI fakeLocation = new URI("classpath:/" + path);
return new UriJavaFileObject(fakeLocation, Thread.currentThread().getContextClassLoader()
.getResource(path));
} catch (URISyntaxException e) {
throw new RuntimeException(e);
}
}
private final URL contents;
public UriJavaFileObject(URI fakeLocation, URL contents) throws URISyntaxException {
super(fakeLocation, JavaFileObject.Kind.SOURCE);
this.contents = contents;
}
@Override
public CharSequence getCharContent(boolean ignored) throws IOException {
return Util.readStreamAsString(contents.openStream());
}
}
/**
* Smoke test to ensure that appropriate errors and warnings are emitted.
*/
public void testErrorsAndWarnings() throws IOException {
testGeneratedMessages(EntityProxyCheckDomainMapping.class);
testGeneratedMessages(EntityProxyMismatchedFind.class);
testGeneratedMessages(EntityProxyMissingDomainLocatorMethods.class);
testGeneratedMessages(EntityProxyMissingDomainType.class);
testGeneratedMessages(MyRequestContext.class);
testGeneratedMessages(MyRequestFactory.class);
testGeneratedMessages(RequestContextMissingDomainType.class);
testGeneratedMessages(RequestContextUsingUnmappedProxy.class,
EntityProxyMissingDomainType.class);
testGeneratedMessages(RequestContextWithMismatchedBoxes.class);
testGeneratedMessages(RequestContextWithMismatchedInstance.class);
}
/**
* The target classes for this method don't contain any {@code @Expect}
* annotations, so this test will verify that they are error- and
* warning-free.
*/
public void testTestClasses() throws IOException {
testGeneratedMessages(RequestFactoryPolymorphicTest.class);
testGeneratedMessages(FindRequest.class);
testGeneratedMessages(LoggingRequest.class);
testGeneratedMessages(SimpleRequestFactory.class);
testGeneratedMessages(TestRequestFactory.class);
}
/**
* The target classes for this method don't contain any {@code @Expect}
* annotations, so this test will verify that they are error- and
* warning-free.
*
* @throws IOException
*/
public void testTestClassesClientOnly() throws IOException {
testGeneratedMessages(true, RequestFactoryPolymorphicTest.class);
testGeneratedMessages(true, FindRequest.class);
testGeneratedMessages(true, LoggingRequest.class);
testGeneratedMessages(true, SimpleRequestFactory.class);
testGeneratedMessages(true, TestRequestFactory.class);
}
private void assertEquals(TreeSet<Diagnostic<? extends JavaFileObject>> expected,
TreeSet<Diagnostic<? extends JavaFileObject>> actual) {
List<Diagnostic<?>> unmatched = new ArrayList<Diagnostic<?>>();
// Remove actual elements from expect, saving any unexpected elements
for (Diagnostic<? extends JavaFileObject> d : actual) {
if (!expected.remove(d)) {
unmatched.add(d);
}
}
assertTrue("Did not see expected errors: " + expected + "\n\nLeftovers :" + unmatched, expected
.isEmpty());
assertTrue("Unexpected errors: " + unmatched, unmatched.isEmpty());
}
private void testGeneratedMessages(Class<?>... classes) throws IOException {
testGeneratedMessages(false, classes);
}
/**
* Run the annotation processor over one or more classes and verify that the
* appropriate messages are generated.
*/
private void testGeneratedMessages(boolean clientOnly, Class<?>... classes) throws IOException {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
if (compiler == null) {
// This test is being run without a full JDK
return;
}
// Don't spray files in random locations
File tempFile = File.createTempFile(RfValidatorTest.class.getSimpleName(), ".jar");
tempFile.deleteOnExit();
JavaFileManager fileManager =
new ValidationTool.JarOrDirectoryOutputFileManager(tempFile, compiler
.getStandardFileManager(null, null, null));
List<JavaFileObject> files = new ArrayList<JavaFileObject>(classes.length);
for (Class<?> clazz : classes) {
JavaFileObject obj = UriJavaFileObject.create(clazz);
files.add(obj);
}
StringWriter errorWriter = new StringWriter();
RfValidator rfValidator = new RfValidator();
rfValidator.setForceErrors(true);
rfValidator.setClientOnly(clientOnly);
DiagnosticCollector<JavaFileObject> expectedCollector =
new DiagnosticCollector<JavaFileObject>();
CompilationTask expectedTask =
compiler.getTask(errorWriter, fileManager, expectedCollector, Arrays.asList("-proc:only"),
null, files);
expectedTask.setProcessors(Arrays.asList(new ExpectCollector()));
expectedTask.call();
DiagnosticCollector<JavaFileObject> actualCollector = new DiagnosticCollector<JavaFileObject>();
CompilationTask actualTask =
compiler.getTask(errorWriter, fileManager, actualCollector, Arrays.asList("-proc:only"),
null, files);
actualTask.setProcessors(Arrays.asList(rfValidator));
actualTask.call();
TreeSet<Diagnostic<? extends JavaFileObject>> expected =
new TreeSet<Diagnostic<? extends JavaFileObject>>(new DiagnosticComparator());
expected.addAll(expectedCollector.getDiagnostics());
TreeSet<Diagnostic<? extends JavaFileObject>> actual =
new TreeSet<Diagnostic<? extends JavaFileObject>>(new DiagnosticComparator());
actual.addAll(actualCollector.getDiagnostics());
assertEquals(expected, actual);
}
}