#1752 Always return mapping target when using update methods with return

This commit is contained in:
Filip Hrisafov 2021-10-30 14:27:24 +02:00
parent 907d605160
commit 166eb699c7
16 changed files with 104 additions and 16 deletions

View File

@ -20,7 +20,7 @@
</#list> </#list>
<#if !mapNullToDefault> <#if !mapNullToDefault>
if ( <#list sourceParametersExcludingPrimitives as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && </#if></#list> ) { if ( <#list sourceParametersExcludingPrimitives as sourceParam>${sourceParam.name} == null<#if sourceParam_has_next> && </#if></#list> ) {
return<#if returnType.name != "void"> null</#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#if finalizerMethod??>.<@includeModel object=finalizerMethod /></#if><#else>null</#if></#if>;
} }
</#if> </#if>

View File

@ -16,8 +16,7 @@
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( ${sourceParameter.name} == null ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
<#-- returned target type starts to miss-align here with target handed via param, TODO is this right? --> return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
return<#if returnType.name != "void"> null</#if>;
<#else> <#else>
<#if resultType.arrayType> <#if resultType.arrayType>
<#if existingInstanceMapping> <#if existingInstanceMapping>

View File

@ -16,7 +16,7 @@
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( ${sourceParameter.name} == null ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
return<#if returnType.name != "void"> null</#if>; return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
<#else> <#else>
<#if existingInstanceMapping> <#if existingInstanceMapping>
${resultName}.clear(); ${resultName}.clear();

View File

@ -17,8 +17,7 @@
</#list> </#list>
if ( ${sourceParameter.name} == null ) { if ( ${sourceParameter.name} == null ) {
<#if !mapNullToDefault> <#if !mapNullToDefault>
<#-- returned target type starts to miss-align here with target handed via param, TODO is this right? --> return<#if returnType.name != "void"> <#if existingInstanceMapping>${resultName}<#else>null</#if></#if>;
return<#if returnType.name != "void"> null</#if>;
<#else> <#else>
<#if resultType.arrayType> <#if resultType.arrayType>
<#if existingInstanceMapping> <#if existingInstanceMapping>

View File

@ -123,15 +123,15 @@ public class ArrayMappingTest {
} }
@ProcessorTest @ProcessorTest
public void shouldMapTargetToNullWhenNullSource() { public void shouldReturnMapTargetWhenNullSource() {
// TODO: What about existing target?
ScientistDto[] existingTarget = ScientistDto[] existingTarget =
new ScientistDto[]{ new ScientistDto( "Jim" ) }; new ScientistDto[]{ new ScientistDto( "Jim" ) };
ScientistDto[] target = ScienceMapper.INSTANCE.scientistsToDtos( null, existingTarget ); ScientistDto[] target = ScienceMapper.INSTANCE.scientistsToDtos( null, existingTarget );
assertThat( target ).isNull(); assertThat( target ).isNotNull();
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).extracting( "name" ).containsOnly( "Jim" ); assertThat( existingTarget ).extracting( "name" ).containsOnly( "Jim" );
} }
@ -143,6 +143,7 @@ public class ArrayMappingTest {
boolean[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); boolean[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( false ); assertThat( target ).containsOnly( false );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( false ); assertThat( existingTarget ).containsOnly( false );
assertThat( ScienceMapper.INSTANCE.nvmMapping( null ) ).isEmpty(); assertThat( ScienceMapper.INSTANCE.nvmMapping( null ) ).isEmpty();
@ -154,6 +155,7 @@ public class ArrayMappingTest {
short[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); short[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( new short[] { 0 } ); assertThat( target ).containsOnly( new short[] { 0 } );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( new short[] { 0 } ); assertThat( existingTarget ).containsOnly( new short[] { 0 } );
} }
@ -163,6 +165,7 @@ public class ArrayMappingTest {
char[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); char[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( new char[] { 0 } ); assertThat( target ).containsOnly( new char[] { 0 } );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( new char[] { 0 } ); assertThat( existingTarget ).containsOnly( new char[] { 0 } );
} }
@ -172,6 +175,7 @@ public class ArrayMappingTest {
int[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); int[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( 0 ); assertThat( target ).containsOnly( 0 );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( 0 ); assertThat( existingTarget ).containsOnly( 0 );
} }
@ -181,6 +185,7 @@ public class ArrayMappingTest {
long[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); long[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( 0L ); assertThat( target ).containsOnly( 0L );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( 0L ); assertThat( existingTarget ).containsOnly( 0L );
} }
@ -190,6 +195,7 @@ public class ArrayMappingTest {
float[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); float[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( 0.0f ); assertThat( target ).containsOnly( 0.0f );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( 0.0f ); assertThat( existingTarget ).containsOnly( 0.0f );
} }
@ -199,6 +205,7 @@ public class ArrayMappingTest {
double[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget ); double[] target = ScienceMapper.INSTANCE.nvmMapping( null, existingTarget );
assertThat( target ).containsOnly( 0.0d ); assertThat( target ).containsOnly( 0.0d );
assertThat( target ).isEqualTo( existingTarget );
assertThat( existingTarget ).containsOnly( 0.0d ); assertThat( existingTarget ).containsOnly( 0.0d );
} }

View File

@ -41,7 +41,8 @@ public class Issue374Test {
Target target2 = new Target(); Target target2 = new Target();
Target result2 = Issue374Mapper.INSTANCE.map2( null, target2 ); Target result2 = Issue374Mapper.INSTANCE.map2( null, target2 );
assertThat( result2 ).isNull(); assertThat( result2 ).isNotNull();
assertThat( result2 ).isEqualTo( target2 );
assertThat( target2.getTest() ).isNull(); assertThat( target2.getTest() ).isNull();
assertThat( target2.getConstant() ).isNull(); assertThat( target2.getConstant() ).isNull();
} }

View File

@ -6,6 +6,7 @@
package org.mapstruct.ap.test.builder.mappingTarget.simple; package org.mapstruct.ap.test.builder.mappingTarget.simple;
import org.junit.jupiter.api.extension.RegisterExtension; import org.junit.jupiter.api.extension.RegisterExtension;
import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
import org.mapstruct.ap.testutil.WithClasses; import org.mapstruct.ap.testutil.WithClasses;
import org.mapstruct.ap.testutil.runner.GeneratedSource; import org.mapstruct.ap.testutil.runner.GeneratedSource;
@ -36,6 +37,18 @@ public class BuilderInfoTargetTest {
assertThat( targetObject.getName() ).isEqualTo( "Bob" ); assertThat( targetObject.getName() ).isEqualTo( "Bob" );
} }
@ProcessorTest
@IssueKey("1752")
public void testSimpleImmutableBuilderFromNullSource() {
SimpleImmutableTarget targetObject = SimpleBuilderMapper.INSTANCE.toImmutable(
null,
SimpleImmutableTarget.builder().age( 3 ).name( "Bob" )
);
assertThat( targetObject ).isNotNull();
assertThat( targetObject.getAge() ).isEqualTo( 3 );
assertThat( targetObject.getName() ).isEqualTo( "Bob" );
}
@ProcessorTest @ProcessorTest
public void testMutableTargetWithBuilder() { public void testMutableTargetWithBuilder() {
SimpleMutableSource source = new SimpleMutableSource(); SimpleMutableSource source = new SimpleMutableSource();

View File

@ -159,7 +159,21 @@ public class DefaultCollectionImplementationTest {
SourceTargetMapper.INSTANCE SourceTargetMapper.INSTANCE
.sourceFoosToTargetFoosUsingTargetParameterAndReturn( createSourceFooList(), target ); .sourceFoosToTargetFoosUsingTargetParameterAndReturn( createSourceFooList(), target );
assertThat( target == result ).isTrue(); assertThat( result ).isSameAs( target );
assertResultList( target );
}
@ProcessorTest
@IssueKey("1752")
public void shouldUseAndReturnTargetParameterForNullMapping() {
List<TargetFoo> target = new ArrayList<>();
target.add( new TargetFoo( "Bob" ) );
target.add( new TargetFoo( "Alice" ) );
Iterable<TargetFoo> result =
SourceTargetMapper.INSTANCE
.sourceFoosToTargetFoosUsingTargetParameterAndReturn( null, target );
assertThat( result ).isSameAs( target );
assertResultList( target ); assertResultList( target );
} }

View File

@ -82,6 +82,20 @@ public class MapMappingTest {
assertResult( target ); assertResult( target );
} }
@ProcessorTest
@IssueKey("1752")
public void shouldCreateMapMethodImplementationWithReturnedTargetParameterAndNullSource() {
Map<Long, Date> target = new HashMap<>();
target.put( 42L, new GregorianCalendar( 1980, Calendar.JANUARY, 1 ).getTime() );
target.put( 121L, new GregorianCalendar( 2013, Calendar.JULY, 20 ).getTime() );
Map<Long, Date> returnedTarget = SourceTargetMapper.INSTANCE
.stringStringMapToLongDateMapUsingTargetParameterAndReturn( null, target );
assertThat( target ).isSameAs( returnedTarget );
assertResult( target );
}
private void assertResult(Map<Long, Date> target) { private void assertResult(Map<Long, Date> target) {
assertThat( target ).isNotNull(); assertThat( target ).isNotNull();
assertThat( target ).hasSize( 2 ); assertThat( target ).hasSize( 2 );

View File

@ -53,6 +53,20 @@ public class InheritanceTest {
assertResult( target ); assertResult( target );
} }
@ProcessorTest
@IssueKey("1752")
public void shouldMapAttributeFromSuperTypeUsingReturnedTargetParameterAndNullSource() {
TargetExt target = new TargetExt();
target.setFoo( 42L );
target.publicFoo = 52L;
target.setBar( 23 );
TargetBase result = SourceTargetMapper.INSTANCE.sourceToTargetWithTargetParameterAndReturn( null, target );
assertThat( target ).isSameAs( result );
assertResult( target );
}
private void assertResult(TargetExt target) { private void assertResult(TargetExt target) {
assertThat( target ).isNotNull(); assertThat( target ).isNotNull();
assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) ); assertThat( target.getFoo() ).isEqualTo( Long.valueOf( 42 ) );

View File

@ -141,6 +141,19 @@ public class DefaultStreamImplementationTest {
assertThat( target ).containsOnly( new TargetFoo( "Bob" ) ); assertThat( target ).containsOnly( new TargetFoo( "Bob" ) );
} }
@ProcessorTest
@IssueKey("1752")
public void shouldUseAndReturnTargetParameterArrayForNullSource() {
TargetFoo[] target = new TargetFoo[1];
target[0] = new TargetFoo( "Bob" );
TargetFoo[] result =
SourceTargetMapper.INSTANCE.streamToArrayUsingTargetParameterAndReturn( null, target );
assertThat( result ).isSameAs( target );
assertThat( target ).isNotNull();
assertThat( target ).containsOnly( new TargetFoo( "Bob" ) );
}
@ProcessorTest @ProcessorTest
public void shouldUseAndReturnTargetParameterForMapping() { public void shouldUseAndReturnTargetParameterForMapping() {
List<TargetFoo> target = new ArrayList<>(); List<TargetFoo> target = new ArrayList<>();
@ -152,6 +165,20 @@ public class DefaultStreamImplementationTest {
assertResultList( target ); assertResultList( target );
} }
@ProcessorTest
@IssueKey("1752")
public void shouldUseAndReturnTargetParameterForNullMapping() {
List<TargetFoo> target = new ArrayList<>();
target.add( new TargetFoo( "Bob" ) );
target.add( new TargetFoo( "Alice" ) );
Iterable<TargetFoo> result =
SourceTargetMapper.INSTANCE
.sourceFoosToTargetFoosUsingTargetParameterAndReturn( null, target );
assertThat( result ).isSameAs( target );
assertResultList( target );
}
@ProcessorTest @ProcessorTest
public void shouldUseDefaultImplementationForListWithoutSetter() { public void shouldUseDefaultImplementationForListWithoutSetter() {
Source source = new Source(); Source source = new Source();

View File

@ -92,7 +92,7 @@ public class ScienceMapperImpl implements ScienceMapper {
@Override @Override
public ScientistDto[] scientistsToDtos(Scientist[] scientists, ScientistDto[] target) { public ScientistDto[] scientistsToDtos(Scientist[] scientists, ScientistDto[] target) {
if ( scientists == null ) { if ( scientists == null ) {
return null; return target;
} }
int i = 0; int i = 0;

View File

@ -128,7 +128,7 @@ public class DomainDtoWithNcvsAlwaysMapperImpl implements DomainDtoWithNcvsAlway
@Override @Override
public Domain updateWithReturn(DtoWithPresenceCheck source, Domain target) { public Domain updateWithReturn(DtoWithPresenceCheck source, Domain target) {
if ( source == null ) { if ( source == null ) {
return null; return target;
} }
if ( target.getStrings() != null ) { if ( target.getStrings() != null ) {

View File

@ -143,7 +143,7 @@ public class DomainDtoWithNvmsNullMapperImpl implements DomainDtoWithNvmsNullMap
@Override @Override
public Domain updateWithReturn(Dto source, Domain target) { public Domain updateWithReturn(Dto source, Domain target) {
if ( source == null ) { if ( source == null ) {
return null; return target;
} }
if ( target.getStrings() != null ) { if ( target.getStrings() != null ) {

View File

@ -128,7 +128,7 @@ public class DomainDtoWithPresenceCheckMapperImpl implements DomainDtoWithPresen
@Override @Override
public Domain updateWithReturn(DtoWithPresenceCheck source, Domain target) { public Domain updateWithReturn(DtoWithPresenceCheck source, Domain target) {
if ( source == null ) { if ( source == null ) {
return null; return target;
} }
if ( target.getStrings() != null ) { if ( target.getStrings() != null ) {

View File

@ -133,7 +133,7 @@ public class SourceTargetMapperImpl implements SourceTargetMapper {
@Override @Override
public Iterable<TargetFoo> sourceFoosToTargetFoosUsingTargetParameterAndReturn(Iterable<SourceFoo> sourceFoos, List<TargetFoo> targetFoos) { public Iterable<TargetFoo> sourceFoosToTargetFoosUsingTargetParameterAndReturn(Iterable<SourceFoo> sourceFoos, List<TargetFoo> targetFoos) {
if ( sourceFoos == null ) { if ( sourceFoos == null ) {
return null; return targetFoos;
} }
targetFoos.clear(); targetFoos.clear();