package br.com.caelum.iogi.collections;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.contains;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.Test;
import br.com.caelum.iogi.Iogi;
import br.com.caelum.iogi.exceptions.InvalidTypeException;
import br.com.caelum.iogi.fixtures.ContainsAParameterizedCollection;
import br.com.caelum.iogi.fixtures.ContainsParameterizedList;
import br.com.caelum.iogi.fixtures.OneString;
import br.com.caelum.iogi.fixtures.TwoArguments;
import br.com.caelum.iogi.parameters.Parameter;
import br.com.caelum.iogi.parameters.Parameters;
import br.com.caelum.iogi.reflection.Target;
import br.com.caelum.iogi.util.DefaultLocaleProvider;
import br.com.caelum.iogi.util.NullDependencyProvider;
public class IndexedListInstantiatorTests {
private final Iogi iogi = new Iogi(new NullDependencyProvider(), new DefaultLocaleProvider());
@Test
public void canInstantiateAListOfStrings() throws Exception {
final Type parameterizedListType = ContainsParameterizedList.class.getDeclaredField("listOfInteger").getGenericType();
final Target<List<Integer>> target = new Target<List<Integer>>(parameterizedListType, "list");
final List<Integer> list = iogi.instantiate(target, new Parameter("list[0]", "1"), new Parameter("list[1]", "2"));
assertThat(list, contains(1, 2));
}
@Test
public void canInstantiateAListOfStringsWithOrder() throws Exception {
final Type parameterizedListType = ContainsParameterizedList.class.getDeclaredField("listOfInteger").getGenericType();
final Target<List<Integer>> target = new Target<List<Integer>>(parameterizedListType, "list");
Parameter[] parameters = { new Parameter("list[0]", "10"), new Parameter("list[2]", "30"), new Parameter("list[1]", "20") };
final List<Integer> list = iogi.instantiate(target, parameters );
assertThat(list, contains(10, 20, 30));
}
@Test
public void canInstantiateAListOfStringsAtSpacedIntervals() throws Exception {
final Type parameterizedListType = ContainsParameterizedList.class.getDeclaredField("listOfInteger").getGenericType();
final Target<List<Integer>> target = new Target<List<Integer>>(parameterizedListType, "list" );
final Parameter parameterAtIndex0 = new Parameter("list[0]", "42");
final Parameter parameterAtIndex10 = new Parameter("list[10]", "666");
final List<Integer> list = iogi.instantiate(target, parameterAtIndex0, parameterAtIndex10);
assertThat(list, contains(42, 666));
}
@Test
public void willInstantiateAnEmptyListIfGivenNoRelevantParameters() throws Exception {
final Type parameterizedListType = ContainsParameterizedList.class.getDeclaredField("listOfInteger").getGenericType();
final Target<List<Object>> target = new Target<List<Object>>(parameterizedListType, "list");
final Collection<Object> list = iogi.instantiate(target);
assertThat(list, is(empty()));
}
@Test
public void canInstantiateAListOfObjects() throws Exception {
final Type type = ContainsParameterizedList.class.getDeclaredField("listOfOneString").getGenericType();
final Target<List<OneString>> target = new Target<List<OneString>>(type, "list");
final List<OneString> list = iogi.instantiate(target, new Parameter("list[0].someString", "ha"), new Parameter("list[1].someString", "he"));
assertEquals("ha", list.get(0).getSomeString());
assertEquals("he", list.get(1).getSomeString());
}
@Test
public void canInstantiateAListOfObjectsWithMoreThanOneConstructorParameter() throws Exception {
final Type type = ContainsParameterizedList.class.getDeclaredField("listOfTwoArguments").getGenericType();
final Target<List<TwoArguments>> target = new Target<List<TwoArguments>>(type , "theList");
final List<TwoArguments> theList = iogi.instantiate(target,
new Parameter("theList[0].one", "10"),
new Parameter("theList[0].two", "11"),
new Parameter("theList[1].one", "20"),
new Parameter("theList[1].two", "21"));
assertEquals(10, theList.get(0).getOne());
assertEquals(11, theList.get(0).getTwo());
assertEquals(20, theList.get(1).getOne());
assertEquals(21, theList.get(1).getTwo());
}
@Test
public void canInstantiateMoreThanOneListFromTheSameParameterList() throws Exception {
final Type type = ContainsParameterizedList.class.getDeclaredField("listOfInteger").getGenericType();
final Target<List<Integer>> firstListTarget = new Target<List<Integer>>(type, "list1");
final Target<List<Integer>> secondListTarget = new Target<List<Integer>>(type, "list2");
final Parameters parameters = new Parameters(Arrays.asList(
new Parameter("list1[0]", "10"),
new Parameter("list1[1]", "11"),
new Parameter("list2[0]", "20"),
new Parameter("list2[1]", "21")));
final List<Integer> firstList = iogi.instantiate(firstListTarget, parameters);
final List<Integer> secondList = iogi.instantiate(secondListTarget, parameters);
assertThat(firstList, contains(10, 11));
assertThat(secondList, contains(20, 21));
}
@Test(expected=InvalidTypeException.class)
public void ifTargetIsAListButIsNotParameterizedThrowAnInvalidTypeException() throws Exception {
final Type rawListType = List.class;
@SuppressWarnings("rawtypes")
final Target<List> target = new Target<List>(rawListType, "foo");
final Parameter parameter = new Parameter("foo[0].bar", "baz");
iogi.instantiate(target, parameter);
}
@Test
public void willIgnoreInvalidListEntries() throws Exception {
final Type type = ContainsParameterizedList.class.getDeclaredField("listOfOneString").getGenericType();
final Target<List<OneString>> target = new Target<List<OneString>>(type, "list");
final List<OneString> list = iogi.instantiate(target,
new Parameter("list[0].someString", "ha"),
new Parameter("irrelevant", "no"),
new Parameter("list", "nope"),
new Parameter("list.someString", "never"),
new Parameter("list[1].someString", "he"));
assertEquals("ha", list.get(0).getSomeString());
assertEquals("he", list.get(1).getSomeString());
}
@Test
public void canInstantiateACollection() throws Exception {
final Type parameterizedCollectionType = ContainsAParameterizedCollection.class.getDeclaredField("collectionOfString").getGenericType();
final Target<Collection<String>> target = new Target<Collection<String>>(parameterizedCollectionType, "col");
final Collection<String> collection = iogi.instantiate(target, new Parameter("col[0]", "bar"), new Parameter("col[1]", "quuux"));
assertThat(collection, contains("bar", "quuux"));
}
}