package de.bitdroid.jaxrs2retrofit.integration;
import com.squareup.javapoet.JavaFile;
import com.sun.net.httpserver.HttpServer;
import com.thoughtworks.qdox.JavaProjectBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import org.apache.commons.io.FileUtils;
import org.glassfish.jersey.jdkhttp.JdkHttpServerFactory;
import org.glassfish.jersey.server.ResourceConfig;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.runner.RunWith;
import java.io.File;
import java.net.URI;
import java.net.URL;
import java.net.URLClassLoader;
import javax.tools.JavaCompiler;
import javax.tools.ToolProvider;
import de.bitdroid.jaxrs2retrofit.GeneratorSettings;
import de.bitdroid.jaxrs2retrofit.RetrofitGenerator;
import de.bitdroid.jaxrs2retrofit.converter.ParamConverterManager;
import de.bitdroid.jaxrs2retrofit.integration.resources.SimpleResource;
import mockit.integration.junit4.JMockit;
import retrofit.RestAdapter;
@RunWith(JMockit.class)
public abstract class AbstractResourceTest<T> {
private static final String
HOST_ADDRESS = "http://localhost:12345/",
OUTPUT_DIR = "testWorkingDir/",
RESOURCES_DIR = System.getProperty("user.dir") + "/src/test/java/" + SimpleResource.class.getPackage().getName().replaceAll("\\.", "/"),
CLIENT_PACKAGE = "client";
protected static final String SYNCHRONOUS_METHODS_PREFIX = "Synchronously";
private final Class<T> resourceClass;
private HttpServer server;
protected Object client;
protected Class clientClass;
protected AbstractResourceTest(Class<T> resourceClass) {
this.resourceClass = resourceClass;
}
@Before
public void startServer() throws Exception {
ResourceConfig config = getResourceConfig();
server = JdkHttpServerFactory.createHttpServer(new URI(HOST_ADDRESS), config, true);
}
@Before
@SuppressWarnings("unchecked")
public void createClientClassAndObject() throws Exception {
// read resource Java files
JavaProjectBuilder builder = new JavaProjectBuilder();
File resourceDir = new File(RESOURCES_DIR);
builder.addSourceTree(resourceDir);
JavaClass resource = builder.getClassByName(resourceClass.getName());
// generate retrofit client
RetrofitGenerator generator = new RetrofitGenerator(new GeneratorSettings(CLIENT_PACKAGE, "", true, true, true, getParamConverterManager()));
JavaFile clientSource = generator.createResource(resource);
// write client to file
File clientFile = new File(OUTPUT_DIR);
Assert.assertTrue(clientFile.mkdir());
clientSource.writeTo(clientFile);
clientSource.writeTo(System.out);
// compile
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
compiler.run(null, null, null, new File(OUTPUT_DIR).getPath() + "/" + CLIENT_PACKAGE + "/" + resourceClass.getSimpleName() + ".java");
ClassLoader classLoader = new URLClassLoader(new URL[] { new URL("file://" + new File(OUTPUT_DIR).getAbsolutePath() + "/") });
this.clientClass = classLoader.loadClass(CLIENT_PACKAGE + "." + resourceClass.getSimpleName());
// setup retrofit client
RestAdapter adapter = getRestAdapterBuilder().build();
this.client = adapter.create(clientClass);
Assert.assertEquals(3 * resourceClass.getDeclaredMethods().length, clientClass.getDeclaredMethods().length);
}
@After
public void stopServer() {
server.stop(2);
}
@After
public void removeGeneratedFiles() throws Exception {
FileUtils.deleteDirectory(new File(OUTPUT_DIR));
}
protected abstract T getMockedResource();
protected RestAdapter.Builder getRestAdapterBuilder() {
return new RestAdapter.Builder().setEndpoint(HOST_ADDRESS);
}
protected ResourceConfig getResourceConfig() {
return new ResourceConfig(getMockedResource().getClass());
}
protected ParamConverterManager getParamConverterManager() {
return ParamConverterManager.getDefaultInstance();
}
}