package com.codiform.moo; import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.junit.Test; import com.codiform.moo.annotation.Access; import com.codiform.moo.annotation.AccessMode; import com.codiform.moo.annotation.CollectionProperty; import com.codiform.moo.annotation.Ignore; import com.codiform.moo.annotation.Optionality; import com.codiform.moo.annotation.Property; import com.codiform.moo.configuration.Configuration; import com.codiform.moo.curry.Translate; import com.codiform.moo.curry.Update; /** * Tests surrounding what happens when a property in a destination class cannot * be found in the source class. * * There are tests in here to deal with source field required/optional in Moo * configuration, but the impact of the {@link Ignore} annotation can be seen in * {@link IgnoreAnnotationTest} */ public class MissingSourcePropertyTest { @Test(expected = MissingSourcePropertyValueException.class ) public void testMooThrowsExceptionIfDestinationFieldNotFoundInSourceOnTranslation() { Source source = new Source( 1, "Moo throws an exception if the destination field isn't found in the source on translation." ); Translate.to( MissingSourceFieldDestination.class ).from( source ); fail( "Moo should have thrown an error due to a missing source property." ); } @Test(expected = MissingSourcePropertyValueException.class ) public void testMooThrowsExceptionIfDestinationFieldNotFoundInSourceOnUpdate() { Source source = new Source( 2, "Moo throws an exception if the destination field isn't found in the source on update." ); MissingSourceFieldDestination destination = new MissingSourceFieldDestination( 242, "To Be Updated", new Date() ); Update.from( source ).to( destination ); fail( "Moo should have thrown an error due to a missing source property." ); } @Test(expected = MissingSourcePropertyValueException.class ) public void testMooThrowsExceptionIfDestinationMethodNotFoundInSourceOnTranslation() { Source source = new Source( 3, "Moo throws an exception if the destination method isn't found in the source on translation." ); Translate.to( MissingSourceMethodDestination.class ).from( source ); fail( "Moo should have thrown an error due to a missing source property." ); } @Test(expected = MissingSourcePropertyValueException.class ) public void testMooThrowsExceptionIfDestinationMethodNotFoundInSourceOnUpdate() { Source source = new Source( 4, "Moo throws an exception if the destination method isn't found in the source on update." ); MissingSourceMethodDestination destination = new MissingSourceMethodDestination( 242, "To Be Updated", new Date() ); Update.from( source ).to( destination ); fail( "Moo should have thrown an error due to a missing source property." ); } @Test public void testMooIgnoresMissingSourceForFieldOnTranslateIfSourcePropertiesNotRequired() { Moo moo = getMooWithOptionalSources(); Source source = new Source( 1, "Moo throws an exception if the destination field isn't found in the source on translation." ); moo.translate( MissingSourceFieldDestination.class ).from( source ); } private Moo getMooWithOptionalSources() { Configuration configuration = new Configuration(); configuration.setSourcePropertiesRequired( false ); return new Moo( configuration ); } @Test public void testMooIgnoresMissingSourceForFieldOnUpdateIfSourcePropertiesNotRequired() { Moo moo = getMooWithOptionalSources(); Source source = new Source( 2, "Moo throws an exception if the destination field isn't found in the source on update." ); MissingSourceFieldDestination destination = new MissingSourceFieldDestination( 242, "To Be Updated", new Date() ); moo.update( source, destination ); } @Test public void testMooIgnoresMissingSourceForMethodOnTranslateIfSourcePropertiesNotRequired() { Moo moo = getMooWithOptionalSources(); Source source = new Source( 3, "Moo throws an exception if the destination method isn't found in the source on translation." ); moo.translate( MissingSourceMethodDestination.class ).from( source ); } @Test public void testMooIgnoresMissingSourceForMethodOnUpdateIfSourcePropertiesNotRequired() { Moo moo = getMooWithOptionalSources(); Source source = new Source( 4, "Moo throws an exception if the destination method isn't found in the source on update." ); MissingSourceMethodDestination destination = new MissingSourceMethodDestination( 242, "To Be Updated", new Date() ); moo.update( source, destination ); } @Test public void testMooIgnoresMissingSourceForMethodMarkedOptionalOnTranslate() { Source source = new Source( 3, "Moo throws an exception if the destination method isn't found in the source on translation." ); Translate.to( OptionalMethodDestination.class ).from( source ); } @Test public void testMooIgnoresMissingSourceForMethodMarkedOptionalOnUpdateIfSourcePropertiesNotRequired() { Source source = new Source( 4, "Moo throws an exception if the destination method isn't found in the source on update." ); OptionalMethodDestination destination = new OptionalMethodDestination( 242, "To Be Updated", new Date() ); Update.from( source ).to( destination ); } public static class Source { private Integer id; private String name; public Source(int id, String name) { this.id = id; this.name = name; } public String getName() { return name; } public Integer getId() { return id; } } @Access(AccessMode.FIELD) public static class MissingSourceFieldDestination { private Integer id; private String name; private Date creationDate; public MissingSourceFieldDestination() { // no-arg constructor for moo } public MissingSourceFieldDestination(int id, String name, Date creationDate) { this.id = id; this.name = name; this.creationDate = creationDate; } public String getName() { return name; } public Integer getId() { return id; } public Date getCreationDate() { return creationDate; } } @Access(AccessMode.METHOD) public static class MissingSourceMethodDestination { private Integer id; private String name; private Date creationDate; public MissingSourceMethodDestination() { // no-arg constructor for moo } public MissingSourceMethodDestination(int id, String name, Date creationDate) { this.id = id; this.name = name; this.creationDate = creationDate; } public String getName() { return name; } public Integer getId() { return id; } public Date getCreationDate() { return creationDate; } public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } } @Access(AccessMode.METHOD) public static class OptionalMethodDestination { private Integer id; private String name; private Date creationDate; private List<Date> accessDates; public OptionalMethodDestination() { // no-arg constructor for moo this.accessDates = new ArrayList<Date>(); } public OptionalMethodDestination(int id, String name, Date creationDate) { this(); this.id = id; this.name = name; this.creationDate = creationDate; } public String getName() { return name; } public Integer getId() { return id; } public Date getCreationDate() { return creationDate; } @Property(optionality = Optionality.OPTIONAL) public void setCreationDate(Date creationDate) { this.creationDate = creationDate; } @CollectionProperty(optionality = Optionality.OPTIONAL) public void setAccessDates(List<Date> accessDates) { this.accessDates = accessDates; } public List<Date> getAccessDates() { return accessDates; } public void setId(Integer id) { this.id = id; } public void setName(String name) { this.name = name; } } }