From 60126183a32573ae437efc8f1f17d1dd9b319ff7 Mon Sep 17 00:00:00 2001
From: Gunnar Morling
Date: Sun, 9 Jun 2013 21:16:24 +0200
Subject: [PATCH] #36 Allowing messages to be used in diagnostic expectations
---
.../mapstruct/ap/MapperGenerationVisitor.java | 4 +-
.../mapstruct/ap/testutil/MapperTestBase.java | 78 ++++++++++++++++++-
.../compilation/annotation/Diagnostic.java | 22 ++++++
.../ExpectedCompilationOutcome.java | 13 +++-
.../model/CompilationOutcomeDescriptor.java | 15 ++--
.../model/DiagnosticDescriptor.java | 9 ++-
6 files changed, 125 insertions(+), 16 deletions(-)
diff --git a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java
index ef7ad7265..a6f7ada9c 100644
--- a/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java
+++ b/processor/src/main/java/org/mapstruct/ap/MapperGenerationVisitor.java
@@ -364,11 +364,11 @@ public class MapperGenerationVisitor extends ElementKindVisitor6 {
if ( declaringMapper == null ) {
if ( parameter.getType().isIterableType() && !returnType.isIterableType() ) {
- reportError( "Can't generate mapping method from iterable type to non-iterable ype.", method );
+ reportError( "Can't generate mapping method from iterable type to non-iterable type.", method );
mappingErroneous = true;
}
if ( !parameter.getType().isIterableType() && returnType.isIterableType() ) {
- reportError( "Can't generate mapping method from non-iterable type to iterable ype.", method );
+ reportError( "Can't generate mapping method from non-iterable type to iterable type.", method );
mappingErroneous = true;
}
if ( parameter.getType().isPrimitive() ) {
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java b/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java
index 1f6257e50..388aa32ab 100644
--- a/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/MapperTestBase.java
@@ -26,6 +26,8 @@ import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
import java.util.List;
import javax.tools.DiagnosticCollector;
import javax.tools.JavaCompiler;
@@ -39,19 +41,26 @@ import org.mapstruct.ap.MappingProcessor;
import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult;
import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome;
import org.mapstruct.ap.testutil.compilation.model.CompilationOutcomeDescriptor;
+import org.mapstruct.ap.testutil.compilation.model.DiagnosticDescriptor;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeMethod;
import static org.fest.assertions.Assertions.assertThat;
/**
- * Base class for all mapper tests. The classes to be compiled for a given test
- * method must be specified via {@link WithClasses}.
+ * Base class for all mapper tests.
+ *
+ * The classes to be compiled for a given test method must be specified via
+ * {@link WithClasses}. Optionally the expected compilation outcome and expected
+ * diagnostics can be specified via {@link ExpectedCompilationOutcome}. If no
+ * outcome is specified, a successful compilation is assumed.
*
* @author Gunnar Morling
*/
public abstract class MapperTestBase {
+ private static final DiagnosticDescriptorComparator COMPARATOR = new DiagnosticDescriptorComparator();
+
private JavaCompiler compiler;
private String sourceDir;
private String classOutputDir;
@@ -118,7 +127,50 @@ public abstract class MapperTestBase {
.isEqualTo( CompilationResult.FAILED );
}
- assertThat( actualResult.getDiagnostics() ).isEqualTo( expectedResult.getDiagnostics() );
+ assertDiagnostics( actualResult.getDiagnostics(), expectedResult.getDiagnostics() );
+ }
+
+ private void assertDiagnostics(List actualDiagnostics,
+ List expectedDiagnostics) {
+
+ Collections.sort( actualDiagnostics, COMPARATOR );
+ Collections.sort( expectedDiagnostics, COMPARATOR );
+
+ Iterator actualIterator = actualDiagnostics.iterator();
+ Iterator expectedIterator = expectedDiagnostics.iterator();
+
+ while ( actualIterator.hasNext() ) {
+ assertThat( expectedIterator.hasNext() ).describedAs(
+ String.format(
+ "Found less diagnostics than expected. Actual: %s; Expected: %s.",
+ actualDiagnostics,
+ expectedDiagnostics
+ )
+ ).isTrue();
+
+ DiagnosticDescriptor actual = actualIterator.next();
+ DiagnosticDescriptor expected = expectedIterator.next();
+
+ assertThat( actual.getSourceFileName() ).isEqualTo( expected.getSourceFileName() );
+ assertThat( actual.getLine() ).isEqualTo( expected.getLine() );
+ assertThat( actual.getKind() ).isEqualTo( expected.getKind() );
+ assertThat( actual.getMessage() ).describedAs(
+ String.format(
+ "%s:%s %s",
+ actual.getSourceFileName(),
+ actual.getLine(),
+ actual.getKind()
+ )
+ ).matches( expected.getMessage() );
+ }
+
+ assertThat( expectedIterator.hasNext() ).describedAs(
+ String.format(
+ "Found more diagnostics than expected. Actual: %s; Expected: %s.",
+ actualDiagnostics,
+ expectedDiagnostics
+ )
+ ).isFalse();
}
/**
@@ -221,4 +273,24 @@ public abstract class MapperTestBase {
}
path.delete();
}
+
+ private static class DiagnosticDescriptorComparator implements Comparator {
+
+ @Override
+ public int compare(DiagnosticDescriptor o1, DiagnosticDescriptor o2) {
+ int result = o1.getSourceFileName().compareTo( o2.getSourceFileName() );
+
+ if ( result != 0 ) {
+ return result;
+ }
+ result = Long.valueOf( o1.getLine() ).compareTo( o2.getLine() );
+ if ( result != 0 ) {
+ return result;
+ }
+
+ // Using the message is not perfect when using regular expressions,
+ // but it's better than nothing
+ return o1.getMessage().compareTo( o2.getMessage() );
+ }
+ }
}
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/Diagnostic.java b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/Diagnostic.java
index 4a3a38a1c..22702130b 100644
--- a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/Diagnostic.java
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/Diagnostic.java
@@ -27,9 +27,31 @@ import javax.tools.Diagnostic.Kind;
*/
public @interface Diagnostic {
+ /**
+ * The type for which the diagnostic was created.
+ *
+ * @return The type for which the diagnostic was created.
+ */
Class> type();
+ /**
+ * The expected kind of diagnostic.
+ *
+ * @return The expected kind of diagnostic.
+ */
Kind kind();
+ /**
+ * The expected line number of the diagnostic.
+ *
+ * @return The expected line number of the diagnostic.
+ */
int line();
+
+ /**
+ * A regular expression matching the expected message of the diagnostic.
+ *
+ * @return A regular expression matching the expected message of the diagnostic.
+ */
+ String messageRegExp() default ".*";
}
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/ExpectedCompilationOutcome.java b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/ExpectedCompilationOutcome.java
index 24e23e3cc..b10069d8c 100644
--- a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/ExpectedCompilationOutcome.java
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/annotation/ExpectedCompilationOutcome.java
@@ -29,7 +29,18 @@ import java.lang.annotation.RetentionPolicy;
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface ExpectedCompilationOutcome {
+
+ /**
+ * The expected result of a compilation.
+ *
+ * @return The expected result of a compilation.
+ */
CompilationResult value();
- Diagnostic[] diagnostics();
+ /**
+ * The expected diagnostics created during a compilation.
+ *
+ * @return The expected diagnostics created during a compilation.
+ */
+ Diagnostic[] diagnostics() default { };
}
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java
index 75e88e5b2..b5b99da91 100644
--- a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/CompilationOutcomeDescriptor.java
@@ -18,10 +18,9 @@
*/
package org.mapstruct.ap.testutil.compilation.model;
+import java.util.ArrayList;
import java.util.Collections;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
import javax.tools.Diagnostic;
import javax.tools.Diagnostic.Kind;
import javax.tools.JavaFileObject;
@@ -37,10 +36,10 @@ import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutco
public class CompilationOutcomeDescriptor {
private CompilationResult compilationResult;
- private Set diagnostics;
+ private List diagnostics;
private CompilationOutcomeDescriptor(CompilationResult compilationResult,
- Set diagnostics) {
+ List diagnostics) {
this.compilationResult = compilationResult;
this.diagnostics = diagnostics;
}
@@ -50,11 +49,11 @@ public class CompilationOutcomeDescriptor {
if ( expectedCompilationResult == null ) {
return new CompilationOutcomeDescriptor(
CompilationResult.SUCCEEDED,
- Collections.emptySet()
+ Collections.emptyList()
);
}
else {
- Set diagnosticDescriptors = new HashSet();
+ List diagnosticDescriptors = new ArrayList();
for ( org.mapstruct.ap.testutil.compilation.annotation.Diagnostic diagnostic :
expectedCompilationResult.diagnostics() ) {
diagnosticDescriptors.add( DiagnosticDescriptor.forDiagnostic( diagnostic ) );
@@ -69,7 +68,7 @@ public class CompilationOutcomeDescriptor {
CompilationResult compilationResult =
compilationSuccessful ? CompilationResult.SUCCEEDED : CompilationResult.FAILED;
- Set diagnosticDescriptors = new HashSet();
+ List diagnosticDescriptors = new ArrayList();
for ( Diagnostic extends JavaFileObject> diagnostic : diagnostics ) {
//ignore notes created by the compiler
if ( diagnostic.getKind() != Kind.NOTE ) {
@@ -84,7 +83,7 @@ public class CompilationOutcomeDescriptor {
return compilationResult;
}
- public Set getDiagnostics() {
+ public List getDiagnostics() {
return diagnostics;
}
diff --git a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/DiagnosticDescriptor.java b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/DiagnosticDescriptor.java
index 2a319f263..f508a766d 100644
--- a/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/DiagnosticDescriptor.java
+++ b/processor/src/test/java/org/mapstruct/ap/testutil/compilation/model/DiagnosticDescriptor.java
@@ -46,7 +46,12 @@ public class DiagnosticDescriptor {
public static DiagnosticDescriptor forDiagnostic(Diagnostic diagnostic) {
String soureFileName = diagnostic.type().getName().replace( ".", File.separator ) + ".java";
- return new DiagnosticDescriptor( soureFileName, diagnostic.kind(), diagnostic.line(), "" );
+ return new DiagnosticDescriptor(
+ soureFileName,
+ diagnostic.kind(),
+ diagnostic.line(),
+ diagnostic.messageRegExp()
+ );
}
public static DiagnosticDescriptor forDiagnostic(String sourceDir,
@@ -55,7 +60,7 @@ public class DiagnosticDescriptor {
getSourceName( sourceDir, diagnostic ),
diagnostic.getKind(),
diagnostic.getLineNumber(),
- ""
+ diagnostic.getMessage( null )
);
}