#2955 Fix @AfterMapping with return type not called for update mappings

This commit is contained in:
Zegveld 2022-10-02 09:34:03 +02:00 committed by Filip Hrisafov
parent 9d2bed09ca
commit 7cfac7c060
2 changed files with 38 additions and 10 deletions

View File

@ -141,7 +141,7 @@ public final class LifecycleMethodResolver {
callbackMethods, callbackMethods,
Collections.emptyList(), Collections.emptyList(),
targetType, targetType,
method.getReturnType(), method.getResultType(),
SelectionCriteria.forLifecycleMethods( selectionParameters ) ); SelectionCriteria.forLifecycleMethods( selectionParameters ) );
return toLifecycleCallbackMethodRefs( return toLifecycleCallbackMethodRefs(

View File

@ -8,6 +8,7 @@ package org.mapstruct.ap.test.callbacks.returning;
import java.util.Arrays; import java.util.Arrays;
import java.util.concurrent.atomic.AtomicReference; import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.AfterEach;
import org.mapstruct.ap.test.callbacks.returning.NodeMapperContext.ContextListener; import org.mapstruct.ap.test.callbacks.returning.NodeMapperContext.ContextListener;
import org.mapstruct.ap.testutil.IssueKey; import org.mapstruct.ap.testutil.IssueKey;
import org.mapstruct.ap.testutil.ProcessorTest; import org.mapstruct.ap.testutil.ProcessorTest;
@ -25,23 +26,29 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
@WithClasses( { Attribute.class, AttributeDto.class, Node.class, NodeDto.class, NodeMapperDefault.class, @WithClasses( { Attribute.class, AttributeDto.class, Node.class, NodeDto.class, NodeMapperDefault.class,
NodeMapperWithContext.class, NodeMapperContext.class, Number.class, NumberMapperDefault.class, NodeMapperWithContext.class, NodeMapperContext.class, Number.class, NumberMapperDefault.class,
NumberMapperContext.class, NumberMapperWithContext.class } ) NumberMapperContext.class, NumberMapperWithContext.class } )
public class CallbacksWithReturnValuesTest { class CallbacksWithReturnValuesTest {
@AfterEach
void cleanup() {
NumberMapperContext.clearCache();
NumberMapperContext.clearVisited();
}
@ProcessorTest @ProcessorTest
public void mappingWithDefaultHandlingRaisesStackOverflowError() { void mappingWithDefaultHandlingRaisesStackOverflowError() {
Node root = buildNodes(); Node root = buildNodes();
assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root ) ) assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root ) )
.isInstanceOf( StackOverflowError.class ); .isInstanceOf( StackOverflowError.class );
} }
@ProcessorTest @ProcessorTest
public void updatingWithDefaultHandlingRaisesStackOverflowError() { void updatingWithDefaultHandlingRaisesStackOverflowError() {
Node root = buildNodes(); Node root = buildNodes();
assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() ) ) assertThatThrownBy( () -> NodeMapperDefault.INSTANCE.nodeToNodeDto( root, new NodeDto() ) )
.isInstanceOf( StackOverflowError.class ); .isInstanceOf( StackOverflowError.class );
} }
@ProcessorTest @ProcessorTest
public void mappingWithContextCorrectlyResolvesCycles() { void mappingWithContextCorrectlyResolvesCycles() {
final AtomicReference<Integer> contextLevel = new AtomicReference<>( null ); final AtomicReference<Integer> contextLevel = new AtomicReference<>( null );
ContextListener contextListener = new ContextListener() { ContextListener contextListener = new ContextListener() {
@Override @Override
@ -75,28 +82,49 @@ public class CallbacksWithReturnValuesTest {
} }
@ProcessorTest @ProcessorTest
public void numberMappingWithoutContextDoesNotUseCache() { void numberMappingWithoutContextDoesNotUseCache() {
Number n1 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 ); Number n1 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 );
Number n2 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 ); Number n2 = NumberMapperDefault.INSTANCE.integerToNumber( 2342 );
assertThat( n1 ).isEqualTo( n2 ); assertThat( n1 ).isEqualTo( n2 );
assertThat( n1 ).isNotSameAs( n2 ); assertThat( n1 ).isNotSameAs( n2 );
} }
@ProcessorTest @ProcessorTest
public void numberMappingWithContextUsesCache() { void numberMappingWithContextUsesCache() {
NumberMapperContext.putCache( new Number( 2342 ) ); NumberMapperContext.putCache( new Number( 2342 ) );
Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 ); Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 );
Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 ); Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 2342 );
assertThat( n1 ).isEqualTo( n2 ); assertThat( n1 ).isEqualTo( n2 );
assertThat( n1 ).isSameAs( n2 ); assertThat( n1 ).isSameAs( n2 );
NumberMapperContext.clearCache();
} }
@ProcessorTest @ProcessorTest
public void numberMappingWithContextCallsVisitNumber() { void numberMappingWithContextCallsVisitNumber() {
Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 1234 ); Number n1 = NumberMapperWithContext.INSTANCE.integerToNumber( 1234 );
Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 5678 ); Number n2 = NumberMapperWithContext.INSTANCE.integerToNumber( 5678 );
assertThat( NumberMapperContext.getVisited() ).isEqualTo( Arrays.asList( n1, n2 ) ); assertThat( NumberMapperContext.getVisited() ).isEqualTo( Arrays.asList( n1, n2 ) );
NumberMapperContext.clearVisited(); }
@ProcessorTest
@IssueKey( "2955" )
void numberUpdateMappingWithContextUsesCacheAndThereforeDoesNotVisitNumber() {
Number target = new Number();
Number expectedReturn = new Number( 2342 );
NumberMapperContext.putCache( expectedReturn );
NumberMapperWithContext.INSTANCE.integerToNumber( 2342, target );
assertThat( NumberMapperContext.getVisited() ).isEmpty();
}
@ProcessorTest
@IssueKey( "2955" )
void numberUpdateMappingWithContextCallsVisitNumber() {
Number target = new Number();
NumberMapperWithContext.INSTANCE.integerToNumber( 2342, target );
assertThat( NumberMapperContext.getVisited() ).contains( target );
} }
} }