/** * Copyright 2012-2017 Gunnar Morling (http://www.gunnarmorling.de/) * and/or other contributors as indicated by the @authors tag. See the * copyright.txt file in the distribution for a full listing of all * contributors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.mapstruct.ap.test.selection.resulttype; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.tools.Diagnostic.Kind; import org.junit.Test; import org.junit.runner.RunWith; import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.compilation.annotation.CompilationResult; import org.mapstruct.ap.testutil.compilation.annotation.Diagnostic; import org.mapstruct.ap.testutil.compilation.annotation.ExpectedCompilationOutcome; import org.mapstruct.ap.testutil.runner.AnnotationProcessorTestRunner; import static org.assertj.core.api.Assertions.assertThat; /** * * @author Sjaak Derksen */ @IssueKey("385") @WithClasses({ IsFruit.class, Fruit.class, FruitDto.class, Apple.class, AppleDto.class }) @RunWith(AnnotationProcessorTestRunner.class) public class InheritanceSelectionTest { @Test @WithClasses( { ConflictingFruitFactory.class, ErroneousFruitMapper.class, Banana.class } ) @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousFruitMapper.class, kind = Kind.ERROR, line = 36, messageRegExp = "Ambiguous factory methods found for creating .*Fruit: " + ".*Apple .*ConflictingFruitFactory\\.createApple\\(\\), " + ".*Banana .*ConflictingFruitFactory\\.createBanana\\(\\)\\.") } ) public void testForkedInheritanceHierarchyShouldResultInAmbigousMappingMethod() { } @Test @WithClasses( { ConflictingFruitFactory.class, ResultTypeSelectingFruitMapper.class, Banana.class } ) public void testResultTypeBasedFactoryMethodSelection() { FruitDto fruitDto = new FruitDto( null ); Fruit fruit = ResultTypeSelectingFruitMapper.INSTANCE.map( fruitDto ); assertThat( fruit ).isNotNull(); assertThat( fruit.getType() ).isEqualTo( "apple" ); } @Test @IssueKey("434") @WithClasses( { ResultTypeConstructingFruitMapper.class } ) public void testResultTypeBasedConstructionOfResult() { FruitDto fruitDto = new FruitDto( null ); Fruit fruit = ResultTypeConstructingFruitMapper.INSTANCE.map( fruitDto ); assertThat( fruit ).isNotNull(); assertThat( fruit.getType() ).isEqualTo( "constructed-by-constructor" ); } @Test @IssueKey("657") @WithClasses( { ResultTypeConstructingFruitInterfaceMapper.class } ) public void testResultTypeBasedConstructionOfResultForInterface() { FruitDto fruitDto = new FruitDto( null ); IsFruit fruit = ResultTypeConstructingFruitInterfaceMapper.INSTANCE.map( fruitDto ); assertThat( fruit ).isNotNull(); assertThat( fruit.getType() ).isEqualTo( "constructed-by-constructor" ); } @Test @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ResultTypeConstructingFruitInterfaceErroneousMapper.class, kind = Kind.ERROR, line = 36, messageRegExp = "The return type .*\\.IsFruit is an abstract class or interface. Provide a non " + "abstract / non interface result type or a factory method." ) } ) @IssueKey("657") @WithClasses({ ResultTypeConstructingFruitInterfaceErroneousMapper.class }) public void testResultTypeBasedConstructionOfResultForInterfaceErroneous() { } @Test @ExpectedCompilationOutcome( value = CompilationResult.FAILED, diagnostics = { @Diagnostic(type = ErroneousFruitMapper2.class, kind = Kind.ERROR, line = 35, messageRegExp = ".*\\.Banana not assignable to: .*\\.Apple.") } ) @IssueKey("434") @WithClasses( { ErroneousFruitMapper2.class, Banana.class } ) public void testResultTypeBasedConstructionOfResultNonAssignable() { } @Test @IssueKey("433") @WithClasses( { FruitFamilyMapper.class, GoldenDeliciousDto.class, GoldenDelicious.class, AppleFamily.class, AppleFamilyDto.class, AppleFactory.class, Banana.class } ) public void testShouldSelectResultTypeInCaseOfAmbiguity() { AppleFamilyDto appleFamilyDto = new AppleFamilyDto(); appleFamilyDto.setApple( new AppleDto("AppleDto") ); AppleFamily result = FruitFamilyMapper.INSTANCE.map( appleFamilyDto ); assertThat( result ).isNotNull(); assertThat( result.getApple() ).isNotNull(); assertThat( result.getApple() ).isInstanceOf( GoldenDelicious.class ); assertThat( result.getApple().getType() ).isEqualTo( "AppleDto" ); } @Test @IssueKey("433") @WithClasses( { FruitFamilyMapper.class, GoldenDeliciousDto.class, GoldenDelicious.class, AppleFamily.class, AppleFamilyDto.class, AppleFactory.class, Banana.class } ) public void testShouldSelectResultTypeInCaseOfAmbiguityForIterable() { List<AppleDto> source = Arrays.asList( new AppleDto( "AppleDto" ) ); List<Apple> result = FruitFamilyMapper.INSTANCE.mapToGoldenDeliciousList( source ); assertThat( result ).isNotNull(); assertThat( result ).isNotEmpty(); assertThat( result.get( 0 ) ).isInstanceOf( GoldenDelicious.class ); assertThat( result.get( 0 ).getType() ).isEqualTo( "AppleDto" ); } @Test @IssueKey("433") @WithClasses( { FruitFamilyMapper.class, GoldenDeliciousDto.class, GoldenDelicious.class, AppleFamily.class, AppleFamilyDto.class, AppleFactory.class, Banana.class } ) public void testShouldSelectResultTypeInCaseOfAmbiguityForMap() { Map<AppleDto, AppleDto> source = new HashMap<AppleDto, AppleDto>(); source.put( new AppleDto( "GoldenDelicious" ), new AppleDto( "AppleDto" ) ); Map<Apple, Apple> result = FruitFamilyMapper.INSTANCE.mapToGoldenDeliciousMap( source ); assertThat( result ).isNotNull(); assertThat( result ).isNotEmpty(); Map.Entry<Apple, Apple> entry = result.entrySet().iterator().next(); assertThat( entry.getKey() ).isInstanceOf( GoldenDelicious.class ); assertThat( entry.getKey().getType() ).isEqualTo( "GoldenDelicious" ); assertThat( entry.getValue() ).isInstanceOf( Apple.class ); assertThat( entry.getValue().getType() ).isEqualTo( "AppleDto" ); } }