package com.fluentinterface; import com.fluentinterface.domain.Person; import com.fluentinterface.domain.PersonBuilder; import com.fluentinterface.proxy.AttributeAccessStrategy; import com.fluentinterface.proxy.impl.FieldAttributeAccessStrategy; import com.fluentinterface.proxy.impl.SetterAttributeAccessStrategy; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import java.util.ArrayDeque; import static com.fluentinterface.ReflectionBuilder.implementationFor; import static java.util.Arrays.asList; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.CoreMatchers.nullValue; import static org.hamcrest.Matchers.notNullValue; import static org.junit.Assert.assertThat; import static org.junit.internal.matchers.IsCollectionContaining.hasItem; @RunWith(Parameterized.class) public class BuilderProxyTest { @Parameterized.Parameters public static Iterable<Object[]> strategies() { return asList( new Object[] {new FieldAttributeAccessStrategy()}, new Object[] {new SetterAttributeAccessStrategy()} ); } private PersonBuilder personBuilder; private AttributeAccessStrategy attributeAccessStrategy; public BuilderProxyTest(AttributeAccessStrategy attributeAccessStrategy) { this.attributeAccessStrategy = attributeAccessStrategy; } @Before public void setup() throws InstantiationException, IllegalAccessException { personBuilder = aPerson(); } private PersonBuilder aPerson() { return implementationFor(PersonBuilder.class) .usingAttributeAccessStrategy(attributeAccessStrategy) .create(); } @Test public void shouldSupportAnyMethodNamedAfterTargetPropertyName() { Person built = personBuilder .forAge(10) .build(); assertThat(built.getAge(), is(10)); built = personBuilder .withAge(10) .build(); assertThat(built.getAge(), is(10)); } @Test public void shouldSetPropertyValueString() { Person built = personBuilder .withName("John Smith") .build(); assertThat(built.getName(), is("John Smith")); } @Test public void shouldSetPropertyValuePrimitive() { Person built = personBuilder .withAge(10) .build(); assertThat(built.getAge(), is(10)); } @Test public void shouldSetPropertyValueToLastOneWhenCalledMultipleTimes() { Person built = personBuilder .withAge(10) .withAge(20) .build(); assertThat(built.getAge(), is(20)); } @Test public void shouldSetPropertyValueArrayToList() { Person built = personBuilder .withFriends( aPerson().withName("John").build(), aPerson().withName("Diane").build()) .build(); assertThat(built.getFriends().size(), is(2)); assertThat(built.getFriends().get(0).getName(), is("John")); assertThat(built.getFriends().get(1).getName(), is("Diane")); } @Test public void shouldSetPropertyValueArrayOfBuildersToCollection() { Person built = personBuilder .withFriends( aPerson().withName("Joe"), aPerson().withName("Blow")) .build(); assertThat(built.getFriends().size(), is(2)); assertThat(built.getFriends().get(0).getName(), is("Joe")); assertThat(built.getFriends().get(1).getName(), is("Blow")); } @Test public void shouldSetPropertyValueArrayOfBuildersToArray() { Person built = personBuilder .withParents( aPerson().withName("Mommy"), aPerson().withName("Daddy")) .build(); assertThat(built.getParents().length, is(2)); assertThat(built.getParents()[0].getName(), is("Mommy")); assertThat(built.getParents()[1].getName(), is("Daddy")); } @Test public void shouldSetPropertyValueCollectionOfBuildersToCollection() { Person built = personBuilder .withFriends(asList( aPerson().withName("Joe"), aPerson().withName("Blow") )) .build(); assertThat(built.getFriends().size(), is(2)); assertThat(built.getFriends().get(0).getName(), is("Joe")); assertThat(built.getFriends().get(1).getName(), is("Blow")); } @Test public void shouldSetPropertyValueCollectionToCollection() { Person built = personBuilder .withParents(asList( aPerson().withName("Mommy").build(), aPerson().withName("Daddy").build())) .build(); assertThat(built.getParents().length, is(2)); assertThat(built.getParents()[0].getName(), is("Mommy")); assertThat(built.getParents()[1].getName(), is("Daddy")); } @Test public void shouldSetPropertyValueArrayToSet() { Person built = personBuilder .withSurnames("Bill", "William", "Guillaume") .build(); assertThat(built.getSurnames().size(), is(3)); assertThat(built.getSurnames(), hasItem("Bill")); assertThat(built.getSurnames(), hasItem("William")); assertThat(built.getSurnames(), hasItem("Guillaume")); } @Test public void shouldSetPropertyValueArrayOfPrimitivesToArrayOfPrimitives() { Person built = personBuilder .withAgesOfMarriages(23, 45) .build(); assertThat(built.getAgesOfMarriages(), is(new int[]{23, 45})); } @Test public void shouldSetPropertyValueBuilderToObject() { Person built = personBuilder .withPartner( aPerson().withName("Diane") ).build(); assertThat(built.getPartner(), notNullValue()); assertThat(built.getPartner().getName(), is("Diane")); } @Test public void shouldCopyCollectionByReferenceWhenCollectionTypeNotSupported() { ArrayDeque queue = new ArrayDeque(); Person built = personBuilder.withQueue(queue).build(); assert built.getQueue() == queue; } @Test public void shouldCallSpecificConstructorWhenBuildMethodCalledWithParameters() { Person person = personBuilder.build("Jeremy", 3); assertThat(person.getName(), is("Jeremy")); assertThat(person.getAge(), is(3)); } @Test public void shouldCallSpecificConstructorWhenBuildMethodCalledWithParametersWithNullValue() { Person person = personBuilder.build("Jeremy", 3, null); assertThat(person.getName(), is("Jeremy")); assertThat(person.getAge(), is(3)); assertThat(person.getPartner(), is(nullValue())); } @Test public void shouldUseBuilderWhenPassedInBuildMethodArguments() { Person person = personBuilder.build("Jeremy", 3, aPerson().withName("Suzana")); assertThat(person.getName(), is("Jeremy")); assertThat(person.getAge(), is(3)); assertThat(person.getPartner().getName(), is("Suzana")); } @Test public void shouldSetPropertyUserSetsAnnotation() { Person built = personBuilder .named("John Smith") .aged(20) .build(); assertThat(built.getName(), is("John Smith")); assertThat(built.getAge(), is(20)); } @Test(expected = IllegalArgumentException.class) public void shouldFailWhenMultipleConstructorsMatchBuildMethodArguments() { personBuilder.build(null, 3); } @Test(expected = IllegalStateException.class) public void shouldFailWhenBuilderUsesAnUnknownProperty() { personBuilder.withAnUnknownProperty("fails").build(); } @Test(expected = IllegalArgumentException.class) public void shouldFailWhenBuilderUsesAnIncompatiblePropertyType() { personBuilder.withAge("fails").build(); } @Test(expected = IllegalStateException.class) public void shouldFailWhenBuilderMethodDoesNotContainPropertyName() { personBuilder.something("fails").build(); } }