package org.hamcrest.generator;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.junit.Test;
public final class QDoxFactoryReaderTest {
@Test public void
extractsOriginalParameterNamesFromSource() {
FactoryMethod method = new FactoryMethod("org.SomeClass", "someMethod", "unusedReturnType");
method.addParameter("java.lang.String", "badParamName");
String input = "" +
"package org;\n" +
"class SomeClass {\n" +
" @org.hamcrest.Factory" +
" public static Matcher someMethod(String realParamName) { ... } \n" +
"}\n";
FactoryMethod factoryMethod = wrapUsingQDoxedSource(method, "org.SomeClass", input);
assertEquals("java.lang.String", factoryMethod.getParameters().get(0).getType());
assertEquals("realParamName", factoryMethod.getParameters().get(0).getName());
}
@Test public void
extractsOriginalGenericParameterNamesFromSource() {
FactoryMethod method = new FactoryMethod("org.SomeClass", "someMethod", "unusedReturnType");
method.addParameter("java.util.Collection<java.lang.String>", "badParamName");
String input = "" +
"package org;\n" +
"class SomeClass {\n" +
" @org.hamcrest.Factory" +
" public static Matcher someMethod(java.util.Collection<String> realParamName) { ... } \n" +
"}\n";
FactoryMethod factoryMethod = wrapUsingQDoxedSource(method, "org.SomeClass", input);
assertEquals("java.util.Collection<java.lang.String>", factoryMethod.getParameters().get(0).getType());
assertEquals("realParamName", factoryMethod.getParameters().get(0).getName());
}
@Test public void
extractsOriginalVarArgParameterNamesFromSource() {
FactoryMethod method = new FactoryMethod("org.SomeClass", "someMethod", "unusedReturnType");
method.addParameter("java.lang.String...", "badParamName");
String input = "" +
"package org;\n" +
"class SomeClass {\n" +
" @org.hamcrest.Factory" +
" public static Matcher someMethod(java.lang.String... realParamName) { ... } \n" +
"}\n";
FactoryMethod factoryMethod = wrapUsingQDoxedSource(method, "org.SomeClass", input);
assertEquals("java.lang.String...", factoryMethod.getParameters().get(0).getType());
assertEquals("realParamName", factoryMethod.getParameters().get(0).getName());
}
@Test public void
extractsOriginalJavaDocFromSource() {
FactoryMethod method = new FactoryMethod("org.SomeClass", "someMethod", "unusedReturnType");
String input = "" +
"package org;\n" +
"class SomeClass {\n" +
" /**\n" +
" * This class does something.\n" +
" *\n" +
" * @return stuff.\n" +
" */\n" +
" @org.hamcrest.Factory" +
" public static Matcher someMethod() { ... } \n" +
"}\n";
FactoryMethod factoryMethod = wrapUsingQDoxedSource(method, "org.SomeClass", input);
assertEquals("This class does something.\n\n@return stuff.\n",
factoryMethod.getJavaDoc());
}
@Test public void
iteratesOverFactoryMethods() throws FileNotFoundException {
final QDoxFactoryReader reader = readerForTestClass("SimpleSetOfMatchers");
final List<FactoryMethod> methods = methodsReadBy(reader);
assertEquals(2, methods.size());
final String expectedClass = "test.SimpleSetOfMatchers";
assertEquals("firstMethod", methods.get(0).getName());
assertEquals(expectedClass, methods.get(0).getMatcherClass());
assertEquals("secondMethod", methods.get(1).getName());
assertEquals(expectedClass, methods.get(1).getMatcherClass());
}
@Test public void
onlyReadsPublicStaticAnnotatedMethodsThatReturnNonVoid() throws FileNotFoundException {
final QDoxFactoryReader reader = readerForTestClass("MatchersWithDodgySignatures");
final List<FactoryMethod> methods = methodsReadBy(reader);
assertEquals(2, methods.size());
assertEquals("anotherGoodMethod", methods.get(0).getName());
assertEquals("goodMethod", methods.get(1).getName());
}
@Test public void
readsFullyQualifiedGenericType() throws FileNotFoundException {
FactoryMethod method = readMethod("GenerifiedMatchers", "generifiedType");
assertEquals("org.hamcrest.Matcher<java.util.Comparator<java.lang.String>>", method.getReturnType());
}
@Test public void
readsNullGenerifiedTypeIfNotPresent() throws FileNotFoundException {
FactoryMethod method = readMethod("GenerifiedMatchers", "noGenerifiedType");
assertEquals("org.hamcrest.Matcher", method.getReturnType());
}
@Test public void
readsGenericsInGenericType() throws FileNotFoundException {
FactoryMethod method = readMethod("GenerifiedMatchers", "crazyType");
assertEquals(
"org.hamcrest.Matcher<java.util.Map<? extends java.util.Set<java.lang.Long>,org.hamcrest.Factory>>",
method.getReturnType());
}
@Test public void
readsParameterTypes() throws FileNotFoundException {
FactoryMethod method = readMethod("ParameterizedMatchers", "withParam");
List<FactoryMethod.Parameter> params = method.getParameters();
assertEquals(3, params.size());
assertEquals("java.lang.String", params.get(0).getType());
assertEquals("int[]", params.get(1).getType());
assertEquals("java.util.Collection<java.lang.Object>", params.get(2).getType());
}
@Test public void
readsArrayAndVarArgParameterTypes() throws FileNotFoundException {
FactoryMethod arrayMethod = readMethod("ParameterizedMatchers", "withArray");
assertEquals("java.lang.String[]", arrayMethod.getParameters().get(0).getType());
FactoryMethod varArgsMethod = readMethod("ParameterizedMatchers", "withVarArgs");
assertEquals("java.lang.String...", varArgsMethod.getParameters().get(0).getType());
}
@Test public void
readsGenerifiedParameterTypes() throws FileNotFoundException {
FactoryMethod method = readMethod("ParameterizedMatchers", "withGenerifiedParam");
assertEquals("java.util.Collection<? extends java.lang.Comparable<java.lang.String>>",
method.getParameters().get(0).getType());
String expected = "java.util.Set<java.lang.String[]>[]";
assertEquals(expected, method.getParameters().get(1).getType());
}
@Test public void
canReadParameterNames() throws FileNotFoundException {
FactoryMethod method = readMethod("ParameterizedMatchers", "withParam");
List<FactoryMethod.Parameter> params = method.getParameters();
assertEquals("someString", params.get(0).getName());
assertEquals("numbers", params.get(1).getName());
assertEquals("things", params.get(2).getName());
}
@Test public void
readsExceptions() throws FileNotFoundException {
FactoryMethod method = readMethod("ExceptionalMatchers", "withExceptions");
List<String> exceptions = method.getExceptions();
assertEquals(3, exceptions.size());
assertEquals("java.lang.Error", exceptions.get(0));
assertEquals("java.io.IOException", exceptions.get(1));
assertEquals("java.lang.RuntimeException", exceptions.get(2));
}
@Test public void
canReadJavaDoc() throws FileNotFoundException {
FactoryMethod method = readMethod("WithJavaDoc", "documented");
assertEquals("Look at me!\n\n@return something\n", method.getJavaDoc());
}
@Test public void
readsGenericTypeParameters() throws FileNotFoundException {
FactoryMethod method = readMethod("G", "x");
assertEquals("T", method.getGenericTypeParameters().get(0));
assertEquals("V extends java.util.List<java.lang.String> & java.lang.Comparable<java.lang.String>",
method.getGenericTypeParameters().get(1));
assertEquals("org.hamcrest.Matcher<java.util.Map<T,V[]>>", method.getReturnType());
assertEquals("java.util.Set<T>", method.getParameters().get(0).getType());
assertEquals("V", method.getParameters().get(1).getType());
}
@Test public void
catchesSubclasses() throws FileNotFoundException {
assertNotNull(readMethod("SubclassOfMatcher", "subclassMethod"));
}
@Test public void
usesCorrectNameForNestedClasses() throws FileNotFoundException {
FactoryMethod method = readMethod("MatcherWithNestedClass", "firstMethod");
assertEquals("test.MatcherWithNestedClass.SpecificMatcher", method.getReturnType());
}
private static List<FactoryMethod> methodsReadBy(final Iterable<FactoryMethod> reader) {
final List<FactoryMethod> extractedMethods = new ArrayList<FactoryMethod>();
for (FactoryMethod factoryMethod : reader) {
extractedMethods.add(factoryMethod);
}
Collections.sort(extractedMethods, new Comparator<FactoryMethod>() {
@Override public int compare(FactoryMethod o1, FactoryMethod o2) {
return o1.getName().compareTo(o2.getName());
}
});
return extractedMethods;
}
private static QDoxFactoryReader readerForTestClass(String name)
throws FileNotFoundException {
QDox qdox = new QDox();
qdox.addSource(new FileReader("src/test/java-source/test/" + name + ".java"));
return new QDoxFactoryReader(qdox, "test." + name);
}
private static FactoryMethod readMethod(String name, String methodName) throws FileNotFoundException {
for (FactoryMethod method : readerForTestClass(name)) {
if (method.getName().equals(methodName)) {
return method;
}
}
return null;
}
private static FactoryMethod wrapUsingQDoxedSource(FactoryMethod originalMethod, String className, String input) {
List<FactoryMethod> originalMethods = new ArrayList<FactoryMethod>();
originalMethods.add(originalMethod);
QDox qdox = new QDox();
qdox.addSource(new StringReader(input));
QDoxFactoryReader qDoxFactoryReader = new QDoxFactoryReader(qdox, className);
return getFirstFactoryMethod(qDoxFactoryReader);
}
private static FactoryMethod getFirstFactoryMethod(QDoxFactoryReader qDoxFactoryReader) {
Iterator<FactoryMethod> iterator = qDoxFactoryReader.iterator();
assertTrue(iterator.hasNext());
return iterator.next();
}
}