/**
* 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.bugs._913;
import static org.assertj.core.api.Assertions.assertThat;
import java.util.HashSet;
import java.util.Set;
import org.junit.Rule;
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.runner.AnnotationProcessorTestRunner;
import org.mapstruct.ap.testutil.runner.GeneratedSource;
/**
* All these test cases test the possible combinations in the SetterMapperForCollections.
*
* The target object is assumed to have getter and setter access.
*
* @author Sjaak Derksen
*/
@RunWith(AnnotationProcessorTestRunner.class)
@WithClasses({
Domain.class,
Dto.class,
DtoWithPresenceCheck.class,
DomainDtoWithNvmsNullMapper.class,
DomainDtoWithNvmsDefaultMapper.class,
DomainDtoWithPresenceCheckMapper.class,
DomainDtoWithNcvsAlwaysMapper.class,
Helper.class})
@IssueKey( "913" )
public class Issue913SetterMapperForCollectionsTest {
@Rule
public final GeneratedSource generatedSource = new GeneratedSource().addComparisonToFixtureFor(
DomainDtoWithNvmsNullMapper.class,
DomainDtoWithNvmsDefaultMapper.class,
DomainDtoWithPresenceCheckMapper.class,
DomainDtoWithNcvsAlwaysMapper.class
);
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return null in the entire mapper, so also for the forged
* mapper. Note the default NVMS is RETURN_NULL.
*
* The generated code should not use a local variable for setting {@code longs}, but it should use a local
* variable for setting {@code strings} as a direct assignment and the copy constructor is used, in case the
* assignment is {@code null} then {@code null} should be set for {@code string}
*/
@Test
public void shouldReturnNullForNvmsReturnNullForCreate() {
Dto dto = new Dto();
Domain domain = DomainDtoWithNvmsNullMapper.INSTANCE.create( dto );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isNull();
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return null in the entire mapper, so also for the forged
* mapper. Note the default NVMS is RETURN_NULL.
*/
@Test
public void shouldReturnNullForNvmsReturnNullForUpdate() {
Dto dto = new Dto();
Domain domain = new Domain();
domain.setLongs( new HashSet<Long>() );
domain.setStrings( new HashSet<String>() );
DomainDtoWithNvmsNullMapper.INSTANCE.update( dto, domain );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isNull();
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return null in the entire mapper, so also for the forged
* mapper. Note the default NVMS is RETURN_NULL.
*
* target (stringsInitialized is Not Null) and source (stringInitialized is Null) target should
* be explicitely set to null
*/
@Test
public void shouldReturnNullForNvmsReturnNullForUpdateWithNonNullTargetAndNullSource() {
Dto dto = new Dto();
dto.setStringsInitialized( null );
Domain domain = new Domain();
domain.setLongs( new HashSet<Long>() );
domain.setStrings( new HashSet<String>() );
DomainDtoWithNvmsNullMapper.INSTANCE.update( dto, domain );
assertThat( domain.getStringsInitialized() ).isNull();
assertThat( domain.getLongsInitialized() ).isNull();
assertThat( domain.getStringsWithDefault() ).containsOnly( "3" );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isNull();
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return null in the entire mapper, so also for the forged
* mapper. Note the default NVMS is RETURN_NULL.
*/
@Test
public void shouldReturnNullForNvmsReturnNullForUpdateWithReturn() {
Dto dto = new Dto();
Domain domain1 = new Domain();
domain1.setLongs( new HashSet<Long>() );
domain1.setStrings( new HashSet<String>() );
Domain domain2 = DomainDtoWithNvmsNullMapper.INSTANCE.updateWithReturn( dto, domain1 );
doControlAsserts( domain1, domain2 );
assertThat( domain1.getStrings() ).isNull();
assertThat( domain1.getLongs() ).isNull();
assertThat( domain2.getStrings() ).isNull();
assertThat( domain2.getLongs() ).isNull();
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return default in the entire mapper, so also for the forged
* mapper. Note the default NVMS is RETURN_NULL.
*
* However, for plain mappings (strings to strings) the result will be null.
*/
@Test
public void shouldReturnDefaultForNvmsReturnDefaultForCreate() {
Dto dto = new Dto();
Domain domain = DomainDtoWithNvmsDefaultMapper.INSTANCE.create( dto );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isEmpty();
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the conversion from
* string to long that return default in the entire mapper, so also for the forged mapper. Note the default NVMS is
* RETURN_NULL.
*
* However, for plain mappings (strings to strings) the result will be null.
*/
@Test
public void shouldReturnDefaultForNvmsReturnDefaultForUpdate() {
Dto dto = new Dto();
Domain domain = new Domain();
Set<Long> longIn = new HashSet<Long>();
longIn.add( 10L );
domain.setLongs( longIn );
domain.setStrings( new HashSet<String>() );
DomainDtoWithNvmsDefaultMapper.INSTANCE.update( dto, domain );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isEmpty();
assertThat( domain.getLongs() ).isSameAs( longIn ); // make sure add all is used.
}
/**
* The null value mapping strategy on type level (Mapper) should generate forged methods for the
* conversion from string to long that return default in the entire mapper, so also for the forged
* mapper. Note the default NVMS is
* RETURN_NULL.
*
* However, for plain mappings (strings to strings) the result will be null.
*
*/
@Test
public void shouldReturnDefaultForNvmsReturnDefaultForUpdateWithReturn() {
Dto dto = new Dto();
Domain domain1 = new Domain();
Set<Long> longIn = new HashSet<Long>();
longIn.add( 10L );
domain1.setLongs( longIn );
domain1.setStrings( new HashSet<String>() );
domain1.getStrings().add( "30" );
Domain domain2 = DomainDtoWithNvmsDefaultMapper.INSTANCE.updateWithReturn( dto, domain1 );
assertThat( domain2 ).isSameAs( domain1 );
doControlAsserts( domain1, domain2 );
assertThat( domain1.getLongs() ).isEqualTo( domain2.getLongs() );
assertThat( domain1.getStrings() ).isNull();
assertThat( domain1.getLongs() ).isEmpty();
assertThat( domain2.getStrings() ).isNull();
assertThat( domain2.getLongs() ).isEmpty();
assertThat( domain1.getLongs() ).isSameAs( longIn ); // make sure that add all is used
assertThat( domain2.getLongs() ).isSameAs( longIn ); // make sure that add all is used
}
/**
* Test create method ICW presence checker. The presence checker is responsible for the null check.
*
*/
@Test
public void shouldReturnNullForCreateWithPresenceChecker() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain = DomainDtoWithPresenceCheckMapper.INSTANCE.create( dto );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isNull();
}
/**
* Test update method ICW presence checker
*
* Similar as in regular mappings, the target property should be left as-is.
*
*/
@IssueKey( "#954")
@Test
public void shouldReturnNullForUpdateWithPresenceChecker() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain = new Domain();
domain.setLongs( new HashSet<Long>() );
domain.getLongs().add( 10L );
domain.setStrings( new HashSet<String>() );
domain.getStrings().add( "30" );
DomainDtoWithPresenceCheckMapper.INSTANCE.update( dto, domain );
doControlAsserts( domain );
assertThat( domain.getStrings() ).containsExactly( "30" );
assertThat( domain.getLongs() ).containsExactly( 10L );
}
/**
* Test update with return method ICW presence checker
*
* Similar as in regular mappings, the target property should be left as-is.
*
*/
@IssueKey( "#954")
@Test
public void shouldReturnNullForUpdateWithReturnWithPresenceChecker() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain1 = new Domain();
domain1.setLongs( new HashSet<Long>() );
domain1.getLongs().add( 10L );
domain1.setStrings( new HashSet<String>() );
domain1.getStrings().add( "30" );
Domain domain2 = DomainDtoWithPresenceCheckMapper.INSTANCE.updateWithReturn( dto, domain1 );
assertThat( domain2 ).isSameAs( domain1 );
doControlAsserts( domain1, domain2 );
assertThat( domain1.getLongs() ).isEqualTo( domain2.getLongs() );
assertThat( domain1.getStrings() ).containsExactly( "30" );
assertThat( domain1.getLongs() ).containsExactly( 10L );
assertThat( domain2.getStrings() ).containsExactly( "30" );
assertThat( domain2.getLongs() ).containsExactly( 10L );
}
/**
* Test create method ICW NullValueCheckStrategy.ALWAYS.
*
*/
@IssueKey( "#954")
@Test
public void shouldReturnNullForCreateWithNcvsAlways() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain = DomainDtoWithNcvsAlwaysMapper.INSTANCE.create( dto );
doControlAsserts( domain );
assertThat( domain.getStrings() ).isNull();
assertThat( domain.getLongs() ).isNull();
}
/**
* Test update method ICW presence checker
*
* Similar as in regular mappings, the target property should be left as-is.
*
*/
@IssueKey( "#954")
@Test
public void shouldReturnNullForUpdateWithNcvsAlways() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain = new Domain();
domain.setLongs( new HashSet<Long>() );
domain.getLongs().add( 10L );
domain.setStrings( new HashSet<String>() );
domain.getStrings().add( "30" );
DomainDtoWithNcvsAlwaysMapper.INSTANCE.update( dto, domain );
doControlAsserts( domain );
assertThat( domain.getStrings() ).containsExactly( "30" );
assertThat( domain.getLongs() ).containsExactly( 10L );
}
/**
* Test update with return method ICW presence checker
*
* Similar as in regular mappings, the target property should be left as-is.
*
*/
@IssueKey( "#954")
@Test
public void shouldReturnNullForUpdateWithReturnWithNcvsAlways() {
DtoWithPresenceCheck dto = new DtoWithPresenceCheck();
Domain domain1 = new Domain();
domain1.setLongs( new HashSet<Long>() );
domain1.getLongs().add( 10L );
domain1.setStrings( new HashSet<String>() );
domain1.getStrings().add( "30" );
Domain domain2 = DomainDtoWithNcvsAlwaysMapper.INSTANCE.updateWithReturn( dto, domain1 );
assertThat( domain2 ).isSameAs( domain1 );
doControlAsserts( domain1, domain2 );
assertThat( domain1.getLongs() ).isEqualTo( domain2.getLongs() );
assertThat( domain1.getStrings() ).containsExactly( "30" );
assertThat( domain1.getLongs() ).containsExactly( 10L );
assertThat( domain2.getStrings() ).containsExactly( "30" );
assertThat( domain2.getLongs() ).containsExactly( 10L );
}
/**
* These assert check if non-null and default mapping is working as expected.
*/
private void doControlAsserts( Domain domain ) {
assertThat( domain.getStringsInitialized() ).containsOnly( "5" );
assertThat( domain.getLongsInitialized() ).containsOnly( 5L );
assertThat( domain.getStringsWithDefault() ).containsOnly( "3" );
}
/**
* These assert check if non-null and default mapping is working as expected.
*/
private void doControlAsserts( Domain domain1, Domain domain2) {
assertThat( domain1 ).isEqualTo( domain2 );
assertThat( domain1.getStringsInitialized() ).containsOnly( "5" );
assertThat( domain1.getLongsInitialized() ).containsOnly( 5L );
assertThat( domain1.getStringsWithDefault() ).containsOnly( "3" );
assertThat( domain2.getStringsInitialized() ).containsOnly( "5" );
assertThat( domain2.getLongsInitialized() ).containsOnly( 5L );
assertThat( domain2.getStringsWithDefault() ).containsOnly( "3" );
assertThat( domain1.getStringsInitialized() ).isEqualTo( domain2.getStringsInitialized() );
assertThat( domain1.getLongsInitialized() ).isEqualTo( domain2.getLongsInitialized() );
assertThat( domain1.getStringsWithDefault() ).isEqualTo( domain2.getStringsWithDefault() );
}
}