Skip to content

Commit

Permalink
add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
h908714124 committed Aug 28, 2019
1 parent 8d129b7 commit e4763fe
Show file tree
Hide file tree
Showing 6 changed files with 132 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,21 @@ CollectorInfo getCollectorInfo(TypeElement collectorClass) {
}

private CollectorType getCollectorType(TypeElement collectorClass) {
Optional<TypeMirror> supplier = Resolver.resolve(
Optional<TypeMirror> supplier = Resolver.typecheck(
Supplier.class,
collectorClass.asType(),
basicInfo.tool()).resolveTypevars();
basicInfo.tool());
if (supplier.isPresent()) {
List<? extends TypeMirror> typeArgs = asDeclared(supplier.get()).getTypeArguments();
if (typeArgs.isEmpty()) {
throw boom("raw Supplier type");
}
return CollectorType.create(basicInfo, typeArgs.get(0), true, collectorClass);
}
TypeMirror collector = Resolver.resolve(
TypeMirror collector = Resolver.typecheck(
Collector.class,
collectorClass.asType(),
basicInfo.tool()).resolveTypevars().orElseThrow(() ->
basicInfo.tool()).orElseThrow(() ->
boom("not a Collector or Supplier<Collector>"));
return CollectorType.create(basicInfo, collector, false, collectorClass);
}
Expand Down
8 changes: 4 additions & 4 deletions core/src/main/java/net/jbock/coerce/MapperClassValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -68,21 +68,21 @@ private void checkBound(TypeElement mapperClass) {
}

private MapperType getMapperType(TypeElement mapperClass) {
Optional<TypeMirror> supplier = Resolver.resolve(
Optional<TypeMirror> supplier = Resolver.typecheck(
Supplier.class,
mapperClass.asType(),
basicInfo.tool()).resolveTypevars();
basicInfo.tool());
if (supplier.isPresent()) {
List<? extends TypeMirror> typeArgs = asDeclared(supplier.get()).getTypeArguments();
if (typeArgs.isEmpty()) {
throw boom("raw Supplier type");
}
return MapperType.create(basicInfo, typeArgs.get(0), true, mapperClass);
}
TypeMirror mapper = Resolver.resolve(
TypeMirror mapper = Resolver.typecheck(
Function.class,
mapperClass.asType(),
basicInfo.tool()).resolveTypevars().orElseThrow(() ->
basicInfo.tool()).orElseThrow(() ->
boom("not a Function or Supplier<Function>"));
return MapperType.create(basicInfo, mapper, false, mapperClass);
}
Expand Down
18 changes: 15 additions & 3 deletions core/src/main/java/net/jbock/coerce/Resolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,19 @@ private Resolver(
this.tool = tool;
}

static Resolver resolve(
/**
* Check if {@code start} is a {@code goal}.
*
* @param goal a type
* @param start a type
* @param tool a tool
*
* @return the {@code goal} type, with typevars resolved
* as far as it can be inferred from {@code start},
* or {@link Optional#empty() empty} if {@code start}
* is not a {@code goal}.
*/
static Optional<TypeMirror> typecheck(
Class<?> goal,
TypeMirror start,
TypeTool tool) {
Expand All @@ -42,7 +54,7 @@ static Resolver resolve(
extensions.add(extension);
nextGoal = tool.erasure(extension.baseClass().asType());
}
return new Resolver(extensions, tool);
return new Resolver(extensions, tool).resolveTypevars();
}

private static Extension findExtension(List<TypeElement> family, TypeMirror goal, TypeTool tool) {
Expand All @@ -68,7 +80,7 @@ private static Extension findExtension(TypeElement typeElement, TypeMirror goal,
return null;
}

Optional<TypeMirror> resolveTypevars() {
private Optional<TypeMirror> resolveTypevars() {
if (extensions.isEmpty()) {
return Optional.empty();
}
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/net/jbock/compiler/TypeTool.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ public TypeElement getTypeElement(Class<?> clazz) {
return elements.getTypeElement(clazz.getCanonicalName());
}

TypeElement asTypeElement(TypeMirror mirror) {
public TypeElement asTypeElement(TypeMirror mirror) {
Element element = types.asElement(mirror);
if (element == null) {
throw new IllegalArgumentException("no element: " + mirror);
Expand Down
62 changes: 62 additions & 0 deletions core/src/test/java/net/jbock/coerce/ResolverTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package net.jbock.coerce;

import net.jbock.compiler.EvaluatingProcessor;
import net.jbock.compiler.TypeTool;
import org.junit.jupiter.api.Test;

import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import java.util.Optional;
import java.util.function.Supplier;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

class ResolverTest {

@Test
void resolves() {

EvaluatingProcessor.source(
"package test;",
"",
"import java.util.function.Supplier;",
"",
"interface StringSupplier extends Supplier<String> { }",
"",
"abstract class Foo implements StringSupplier { }"
).run("Mapper", (elements, types) -> {
TypeTool tool = new TypeTool(elements, types);
TypeElement mapper = elements.getTypeElement("test.Foo");
Optional<TypeMirror> result = Resolver.typecheck(Supplier.class, mapper.asType(), tool);
assertTrue(result.isPresent());
TypeMirror typeMirror = result.get();
DeclaredType declared = TypeTool.asDeclared(typeMirror);
assertEquals(1, declared.getTypeArguments().size());
TypeMirror typeParameter = declared.getTypeArguments().get(0);
TypeElement string = elements.getTypeElement("java.lang.String");
assertTrue(types.isSameType(string.asType(), typeParameter));
});
}

@Test
void doesNotResolve() {

EvaluatingProcessor.source(
"package test;",
"",
"import java.util.function.Supplier;",
"",
"interface StringSupplier extends Supplier<String> { }",
"",
"abstract class Foo implements StringSupplier { }"
).run("Mapper", (elements, types) -> {
TypeTool tool = new TypeTool(elements, types);
TypeElement mapper = elements.getTypeElement("test.Foo");
Optional<TypeMirror> result = Resolver.typecheck(String.class, mapper.asType(), tool);
assertFalse(result.isPresent());
});
}
}
46 changes: 46 additions & 0 deletions core/src/test/java/net/jbock/compiler/MapperTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,52 @@ void validMapperTypeParameterWithBounds() {
.compilesWithoutError();
}

@Test
void validMapperTypeParameterSupplierWithBounds() {
List<String> sourceLines = withImports(
"@CommandLineArguments",
"abstract class ValidArguments {",
"",
" @Parameter(shortName = 'x',",
" mappedBy = IdentityMapper.class)",
" abstract String string();",
"",
" static class IdentityMapper<E extends java.lang.CharSequence> implements Supplier<Function<E, E>> {",
" public Function<E, E> get() {",
" return null;",
" }",
" }",
"}");
JavaFileObject javaFile = forSourceLines("test.ValidArguments", sourceLines);
assertAbout(javaSources()).that(singletonList(javaFile))
.processedWith(new Processor())
.compilesWithoutError();
}

@Test
void invalidMapperTypeParameterSupplierWithBounds() {
List<String> sourceLines = withImports(
"@CommandLineArguments",
"abstract class InvalidArguments {",
"",
" @Parameter(shortName = 'x',",
" mappedBy = IdentityMapper.class)",
" abstract String string();",
"",
" static class IdentityMapper<E extends Integer> implements Supplier<Function<E, E>> {",
" public Function<E, E> get() {",
" return null;",
" }",
" }",
"}");
JavaFileObject javaFile = forSourceLines("test.InvalidArguments", sourceLines);
assertAbout(javaSources()).that(singletonList(javaFile))
.processedWith(new Processor())
.failsToCompile()
.withErrorContaining("There is a problem with the mapper class: Invalid bounds on the type parameters of the mapper class.");
}


@Test
void invalidFlagMapper() {
List<String> sourceLines = withImports(
Expand Down

0 comments on commit e4763fe

Please sign in to comment.