package io.norberg.automatter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import java.util.List;
import java.util.Map;
import static java.util.Collections.singletonMap;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public class MapFieldBuilderTest {
public @Rule ExpectedException expectedException = ExpectedException.none();
@AutoMatter
interface Maps {
Map<String, Integer> prices();
Map<Integer, String> oxen();
Map<Integer, String> serial();
Map<Integer, List<String>> lists();
}
MapsBuilder builder;
@Before
public void setUp() {
builder = new MapsBuilder();
}
@Test
public void testDefaults() {
assertThat(builder.prices().isEmpty(), is(true));
final Maps maps = builder.build();
assertThat(maps.prices().isEmpty(), is(true));
}
@Test
public void verifyBuilderMapIsMutable() {
builder.putPrice("apple", 17);
final Map<String, Integer> prices = builder.prices();
prices.remove("apple");
prices.put("orange", 18);
assertThat(builder.prices(), is(singletonMap("orange", 18)));
final Maps maps = builder.build();
assertThat(maps.prices(), is(singletonMap("orange", 18)));
}
@Test
public void verifyMutatingBuilderMapDoesNotChangeValue() {
final Maps maps1 = builder
.prices("apple", 17)
.build();
builder.putPrice("orange", 18);
final Maps maps2 = builder.build();
assertThat(maps1.prices(), is(singletonMap("apple", 17)));
assertEquals(ImmutableMap.of("apple", 17, "orange", 18), maps2.prices());
}
@Test
public void testPuttingMultipleEntries() {
builder.prices("a", 1);
assertEquals(ImmutableMap.of("a", 1), builder.prices());
assertEquals(ImmutableMap.of("a", 1), builder.build().prices());
builder.prices("a", 1, "b", 2);
assertEquals(ImmutableMap.of("a", 1, "b", 2), builder.prices());
assertEquals(ImmutableMap.of("a", 1, "b", 2), builder.build().prices());
builder.prices("a", 1, "b", 2, "c", 3);
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3), builder.prices());
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3), builder.build().prices());
builder.prices("a", 1, "b", 2, "c", 3, "d", 4);
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3, "d", 4), builder.prices());
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3, "d", 4), builder.build().prices());
builder.prices("a", 1, "b", 2, "c", 3, "d", 4, "e", 5);
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5), builder.prices());
assertEquals(ImmutableMap.of("a", 1, "b", 2, "c", 3, "d", 4, "e", 5), builder.build().prices());
}
@Test
public void verifyPuttingMultipleEntriesWithNullKeyThrowsNPE() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("prices: k5");
builder.prices("a", 1, "b", 2, "c", 3, "d", 4, null, 5);
}
@Test
public void verifyPuttingMultipleEntriesWithNullValueThrowsNPE() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("prices: v5");
builder.prices("a", 1, "b", 2, "c", 3, "d", 4, "f", null);
}
@Test
public void testPuttingAdditionalEntries() {
builder.putPrice("a", 1);
assertEquals(ImmutableMap.of("a", 1), builder.prices());
assertEquals(ImmutableMap.of("a", 1), builder.build().prices());
builder.putPrice("b", 2);
assertEquals(ImmutableMap.of("a", 1, "b", 2), builder.prices());
assertEquals(ImmutableMap.of("a", 1, "b", 2), builder.build().prices());
}
@Test(expected = UnsupportedOperationException.class)
public void verifyValueMapIsImmutable1() {
final Maps maps = builder
.putPrice("apple", 17)
.putPrice("orange", 18)
.build();
maps.prices().remove("apple");
}
@Test(expected = UnsupportedOperationException.class)
public void verifyValueListIsImmutable2() {
final Maps maps = builder
.putPrice("apple", 17)
.build();
maps.prices().put("orange", 18);
}
@Test(expected = UnsupportedOperationException.class)
public void verifyValueListIsImmutable3() {
final Maps maps = builder
.putPrice("apple", 17)
.build();
maps.prices().clear();
}
@Test
public void testEnglishPlurals() {
final Maps maps = builder.putOx(17, "foo").putOx(4711, "bar").build();
assertEquals(ImmutableMap.of(17, "foo", 4711, "bar"), maps.oxen());
}
@Test
public void testSingular() {
final Maps maps = builder.serial(1, "a", 3, "b").build();
assertEquals(ImmutableMap.of(1, "a", 3, "b"), maps.serial());
}
@Test
public void verifyPuttingNullKeyThrowsNPE() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("price: key");
builder.putPrice(null, 17);
}
@Test
public void verifyPuttingNullValueThrowsNPE() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("price: value");
builder.putPrice("apple", null);
}
@Test
public void verifySettingNullMapThrowsNPE() {
expectedException.expect(NullPointerException.class);
expectedException.expectMessage("prices");
builder.prices(null);
}
@Test
public void verifySettingExtendingValue() {
builder.lists(ImmutableMap.of(1, ImmutableList.of("foo", "bar")));
}
@Test
public void verifyMapMethodsReplaceValue() {
final Maps onlyApples = builder.prices("apples", 2, "pears", 3)
.prices("apples", 4)
.build();
assertEquals(ImmutableMap.of("apples", 4), onlyApples.prices());
final Maps pearsAndOranges = MapsBuilder.from(onlyApples)
.prices("pears", 5, "orange", 6)
.build();
assertEquals(ImmutableMap.of("pears", 5, "orange", 6), pearsAndOranges.prices());
}
}