#1675 Tests should run properly in Java 11

* Add Travis CI build matrix to run build on OpenJDK 11 and EA
* Add regex for the Java 11 Generated annotation in order for the JavaFileAssert to work properly
* Do not use eclipse compiler if running on Java 9+
* Add JDK11 util compiler that reports all errors (also when multiple on same line)
* Whitelist jaxb-api to the test compilation classpath
* Add specific ignores for running some tests with Java 11 (See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+)
This commit is contained in:
Filip Hrisafov 2019-03-09 19:37:27 +01:00
parent ae3758674a
commit 643cc85e50
11 changed files with 221 additions and 4 deletions

View File

@ -1,11 +1,24 @@
language: java language: java
jdk:
- oraclejdk8
install: true install: true
script: mvn clean install -DprocessorIntegrationTest.toolchainsFile=etc/toolchains-travis-jenkins.xml -B -V script: mvn clean install -DprocessorIntegrationTest.toolchainsFile=etc/toolchains-travis-jenkins.xml -B -V
after_success: after_success:
- mvn jacoco:report && bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports" - mvn jacoco:report && bash <(curl -s https://codecov.io/bash) || echo "Codecov did not collect coverage reports"
matrix:
include:
- jdk: oraclejdk8
- jdk: openjdk11
# Only run the processor and its dependencies
# The integration tests are using the maven toolchain and that is not yet ready for Java 11
# There is an issue with the documentation so skip it
script: mvn -B -V clean install -pl processor -am
# Only run the processor and its dependencies
# The integration tests are using the maven toolchain and that is not yet ready for Java EA
# There is an issue with the documentation so skip it
- jdk: openjdk-ea
script: mvn -B -V clean install -pl processor -am
allow_failures:
- jdk: openjdk-ea
deploy: deploy:
provider: script provider: script
script: "test ${TRAVIS_TEST_RESULT} -eq 0 && mvn -s etc/travis-settings.xml -DskipTests=true deploy" script: "test ${TRAVIS_TEST_RESULT} -eq 0 && mvn -s etc/travis-settings.xml -DskipTests=true deploy"

View File

@ -22,6 +22,9 @@ import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
import org.mapstruct.ap.testutil.runner.Compiler;
import org.mapstruct.ap.testutil.runner.DisabledOnCompiler;
import org.mapstruct.ap.testutil.runner.EnabledOnCompiler;
/** /**
* Tests application of format strings for conversions between strings and dates. * Tests application of format strings for conversions between strings and dates.
@ -43,6 +46,8 @@ public class DateConversionTest {
} }
@Test @Test
@DisabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void shouldApplyDateFormatForConversions() { public void shouldApplyDateFormatForConversions() {
Source source = new Source(); Source source = new Source();
source.setDate( new GregorianCalendar( 2013, 6, 6 ).getTime() ); source.setDate( new GregorianCalendar( 2013, 6, 6 ).getTime() );
@ -56,6 +61,23 @@ public class DateConversionTest {
} }
@Test @Test
@EnabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void shouldApplyDateFormatForConversionsJdk11() {
Source source = new Source();
source.setDate( new GregorianCalendar( 2013, 6, 6 ).getTime() );
source.setAnotherDate( new GregorianCalendar( 2013, 1, 14 ).getTime() );
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( source );
assertThat( target ).isNotNull();
assertThat( target.getDate() ).isEqualTo( "06.07.2013" );
assertThat( target.getAnotherDate() ).isEqualTo( "14.02.13, 00:00" );
}
@Test
@DisabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void shouldApplyDateFormatForConversionInReverseMapping() { public void shouldApplyDateFormatForConversionInReverseMapping() {
Target target = new Target(); Target target = new Target();
target.setDate( "06.07.2013" ); target.setDate( "06.07.2013" );
@ -68,6 +90,21 @@ public class DateConversionTest {
assertThat( source.getAnotherDate() ).isEqualTo( new GregorianCalendar( 2013, 1, 14, 8, 30 ).getTime() ); assertThat( source.getAnotherDate() ).isEqualTo( new GregorianCalendar( 2013, 1, 14, 8, 30 ).getTime() );
} }
@Test
@EnabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void shouldApplyDateFormatForConversionInReverseMappingJdk11() {
Target target = new Target();
target.setDate( "06.07.2013" );
target.setAnotherDate( "14.02.13, 8:30" );
Source source = SourceTargetMapper.INSTANCE.targetToSource( target );
assertThat( source ).isNotNull();
assertThat( source.getDate() ).isEqualTo( new GregorianCalendar( 2013, 6, 6 ).getTime() );
assertThat( source.getAnotherDate() ).isEqualTo( new GregorianCalendar( 2013, 1, 14, 8, 30 ).getTime() );
}
@Test @Test
public void shouldApplyStringConversionForIterableMethod() { public void shouldApplyStringConversionForIterableMethod() {
List<Date> dates = Arrays.asList( List<Date> dates = Arrays.asList(

View File

@ -22,6 +22,9 @@ import org.junit.runner.RunWith;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner;
import org.mapstruct.ap.testutil.runner.Compiler;
import org.mapstruct.ap.testutil.runner.DisabledOnCompiler;
import org.mapstruct.ap.testutil.runner.EnabledOnCompiler;
/** /**
* Tests the conversion between Joda-Time types and String/Date/Calendar. * Tests the conversion between Joda-Time types and String/Date/Calendar.
@ -75,6 +78,8 @@ public class JodaConversionTest {
} }
@Test @Test
@DisabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void testSourceToTargetMappingForStrings() { public void testSourceToTargetMappingForStrings() {
Source src = new Source(); Source src = new Source();
src.setLocalTime( new LocalTime( 0, 0 ) ); src.setLocalTime( new LocalTime( 0, 0 ) );
@ -100,6 +105,34 @@ public class JodaConversionTest {
assertThat( target.getLocalTime() ).isEqualTo( "00:00:00" ); assertThat( target.getLocalTime() ).isEqualTo( "00:00:00" );
} }
@Test
@EnabledOnCompiler(Compiler.JDK11)
// See https://bugs.openjdk.java.net/browse/JDK-8211262, there is a difference in the default formats on Java 9+
public void testSourceToTargetMappingForStringsJdk11() {
Source src = new Source();
src.setLocalTime( new LocalTime( 0, 0 ) );
src.setLocalDate( new LocalDate( 2014, 1, 1 ) );
src.setLocalDateTime( new LocalDateTime( 2014, 1, 1, 0, 0 ) );
src.setDateTime( new DateTime( 2014, 1, 1, 0, 0, 0, DateTimeZone.UTC ) );
// with given format
Target target = SourceTargetMapper.INSTANCE.sourceToTarget( src );
assertThat( target ).isNotNull();
assertThat( target.getDateTime() ).isEqualTo( "01.01.2014 00:00 UTC" );
assertThat( target.getLocalDateTime() ).isEqualTo( "01.01.2014 00:00" );
assertThat( target.getLocalDate() ).isEqualTo( "01.01.2014" );
assertThat( target.getLocalTime() ).isEqualTo( "00:00" );
// and now with default mappings
target = SourceTargetMapper.INSTANCE.sourceToTargetDefaultMapping( src );
assertThat( target ).isNotNull();
assertThat( target.getDateTime() ).isEqualTo( "1. Januar 2014 um 00:00:00 UTC" );
assertThat( target.getLocalDateTime() ).isEqualTo( "1. Januar 2014 um 00:00:00" );
assertThat( target.getLocalDate() ).isEqualTo( "1. Januar 2014" );
assertThat( target.getLocalTime() ).isEqualTo( "00:00:00" );
}
@Test @Test
public void testStringToDateTime() { public void testStringToDateTime() {
String dateTimeAsString = "01.01.2014 00:00 UTC"; String dateTimeAsString = "01.01.2014 00:00 UTC";

View File

@ -38,6 +38,8 @@ public class JavaFileAssert extends FileAssert {
"\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+\\d{4}\","; "\"\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+\\d{4}\",";
private static final String GENERATED_COMMENTS_REGEX = "\\s+comments = \"version: , compiler: .*, environment: " + private static final String GENERATED_COMMENTS_REGEX = "\\s+comments = \"version: , compiler: .*, environment: " +
".*\""; ".*\"";
private static final String IMPORT_GENERATED_ANNOTATION_REGEX = "import javax\\.annotation\\.(processing\\.)?" +
"Generated;";
private Diff diff = new Diff(); private Diff diff = new Diff();
@ -135,7 +137,8 @@ public class JavaFileAssert extends FileAssert {
else if ( delta.getType() == Delta.TYPE.CHANGE ) { else if ( delta.getType() == Delta.TYPE.CHANGE ) {
List<String> lines = delta.getOriginal().getLines(); List<String> lines = delta.getOriginal().getLines();
if ( lines.size() == 1 ) { if ( lines.size() == 1 ) {
return lines.get( 0 ).matches( GENERATED_DATE_REGEX ); return lines.get( 0 ).matches( GENERATED_DATE_REGEX ) ||
lines.get( 0 ).matches( IMPORT_GENERATED_ANNOTATION_REGEX );
} }
else if ( lines.size() == 2 ) { else if ( lines.size() == 2 ) {
return lines.get( 0 ).matches( GENERATED_DATE_REGEX ) && return lines.get( 0 ).matches( GENERATED_DATE_REGEX ) &&

View File

@ -37,6 +37,19 @@ import org.mapstruct.ap.testutil.compilation.annotation.ProcessorOption;
* @author Andreas Gudian * @author Andreas Gudian
*/ */
public class AnnotationProcessorTestRunner extends ParentRunner<Runner> { public class AnnotationProcessorTestRunner extends ParentRunner<Runner> {
private static final boolean IS_AT_LEAST_JAVA_9 = isIsAtLeastJava9();
private static boolean isIsAtLeastJava9() {
try {
Runtime.class.getMethod( "version" );
return true;
}
catch ( NoSuchMethodException e ) {
return false;
}
}
private final List<Runner> runners; private final List<Runner> runners;
/** /**
@ -57,6 +70,12 @@ public class AnnotationProcessorTestRunner extends ParentRunner<Runner> {
if (singleCompiler != null) { if (singleCompiler != null) {
return Arrays.<Runner> asList( new InnerAnnotationProcessorRunner( klass, singleCompiler.value() ) ); return Arrays.<Runner> asList( new InnerAnnotationProcessorRunner( klass, singleCompiler.value() ) );
} }
else if ( IS_AT_LEAST_JAVA_9 ) {
// Current tycho-compiler-jdt (0.26.0) is not compatible with Java 11
// Updating to latest version 1.3.0 fails some tests
// Once https://github.com/mapstruct/mapstruct/pull/1587 is resolved we can remove this line
return Arrays.asList( new InnerAnnotationProcessorRunner( klass, Compiler.JDK11 ) );
}
return Arrays.<Runner> asList( return Arrays.<Runner> asList(
new InnerAnnotationProcessorRunner( klass, Compiler.JDK ), new InnerAnnotationProcessorRunner( klass, Compiler.JDK ),

View File

@ -10,5 +10,5 @@ package org.mapstruct.ap.testutil.runner;
* *
*/ */
public enum Compiler { public enum Compiler {
JDK, ECLIPSE; JDK, JDK11, ECLIPSE;
} }

View File

@ -128,6 +128,7 @@ abstract class CompilingStatement extends Statement {
"javax.inject", "javax.inject",
"spring-beans", "spring-beans",
"spring-context", "spring-context",
"jaxb-api",
"joda-time" }; "joda-time" };
return filterBootClassPath( whitelist ); return filterBootClassPath( whitelist );

View File

@ -0,0 +1,26 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.testutil.runner;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This should be used with care.
* This is similar to the JUnit 5 DisabledOnJre (once we have JUnit 5 we can replace this one)
*
* @author Filip Hrisafov
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DisabledOnCompiler {
/**
* @return The compiler to use.
*/
Compiler value();
}

View File

@ -0,0 +1,26 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.testutil.runner;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* This should be used with care.
* This is similar to the JUnit 5 EnabledOnJre (once we have JUnit 5 we can replace this one)
*
* @author Filip Hrisafov
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EnabledOnCompiler {
/**
* @return The compiler to use.
*/
Compiler value();
}

View File

@ -60,6 +60,25 @@ class InnerAnnotationProcessorRunner extends BlockJUnit4ClassRunner {
Thread.currentThread().setContextClassLoader( testClassLoader ); Thread.currentThread().setContextClassLoader( testClassLoader );
} }
@Override
protected boolean isIgnored(FrameworkMethod child) {
return super.isIgnored( child ) || isIgnoredForCompiler( child );
}
protected boolean isIgnoredForCompiler(FrameworkMethod child) {
EnabledOnCompiler enabledOnCompiler = child.getAnnotation( EnabledOnCompiler.class );
if ( enabledOnCompiler != null ) {
return enabledOnCompiler.value() != compiler;
}
DisabledOnCompiler disabledOnCompiler = child.getAnnotation( DisabledOnCompiler.class );
if ( disabledOnCompiler != null ) {
return disabledOnCompiler.value() == compiler;
}
return false;
}
@Override @Override
protected TestClass createTestClass(final Class<?> testClass) { protected TestClass createTestClass(final Class<?> testClass) {
replacableTestClass = new ReplacableTestClass( testClass ); replacableTestClass = new ReplacableTestClass( testClass );
@ -98,6 +117,9 @@ class InnerAnnotationProcessorRunner extends BlockJUnit4ClassRunner {
if ( compiler == Compiler.JDK ) { if ( compiler == Compiler.JDK ) {
return new JdkCompilingStatement( method, compilationCache ); return new JdkCompilingStatement( method, compilationCache );
} }
else if ( compiler == Compiler.JDK11 ) {
return new Jdk11CompilingStatement( method, compilationCache );
}
else { else {
return new EclipseCompilingStatement( method, compilationCache ); return new EclipseCompilingStatement( method, compilationCache );
} }

View File

@ -0,0 +1,37 @@
/*
* Copyright MapStruct Authors.
*
* Licensed under the Apache License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
*/
package org.mapstruct.ap.testutil.runner;
import java.util.List;
import org.junit.runners.model.FrameworkMethod;
import org.mapstruct.ap.testutil.compilation.model.DiagnosticDescriptor;
/**
* Statement that uses the JDK compiler to compile.
*
* @author Filip Hrisafov
*/
class Jdk11CompilingStatement extends JdkCompilingStatement {
Jdk11CompilingStatement(FrameworkMethod method, CompilationCache compilationCache) {
super( method, compilationCache );
}
/**
* The JDK 11 compiler reports all ERROR diagnostics properly. Also when there are multiple per line.
*/
@Override
protected List<DiagnosticDescriptor> filterExpectedDiagnostics(List<DiagnosticDescriptor> expectedDiagnostics) {
return expectedDiagnostics;
}
@Override
protected String getPathSuffix() {
return "_jdk";
}
}