package com.codepoetics.octarine.json;
import com.codepoetics.octarine.json.deserialisation.ListDeserialiser;
import com.codepoetics.octarine.json.example.Address;
import com.codepoetics.octarine.json.example.Person;
import com.codepoetics.octarine.json.serialisation.ListSerialiser;
import com.codepoetics.octarine.json.serialisation.MapSerialiser;
import com.codepoetics.octarine.json.serialisation.ReflectiveRecordSerialiser;
import com.codepoetics.octarine.records.Record;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.junit.Test;
import java.awt.*;
import java.io.IOException;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;
import static com.codepoetics.octarine.Octarine.$$;
import static com.codepoetics.octarine.json.serialisation.Serialisers.toInteger;
import static java.util.Arrays.asList;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
public class SerialisationTest {
@Test
public void
writes_person_as_json() {
String json = Person.serialiser.toString($$(
Person.name.of("Dominic"),
Person.age.of(39),
Person.favouriteColour.of(Color.RED),
Person.address.of(Address.addressLines.of("13 Rue Morgue", "PO3 1TP"))));
assertThat(json, equalTo("{\"name\":\"Dominic\",\"age\":39,\"favourite colour\":\"0xFF0000\",\"address\":{\"addressLines\":[\"13 Rue Morgue\",\"PO3 1TP\"]}}"));
}
@Test
public void
tolerates_missing_values() {
String json = Person.serialiser.toString($$(
Person.name.of("Dominic"),
Person.age.of(39),
Person.address.of(Address.addressLines.of("13 Rue Morgue", "PO3 1TP"))));
assertThat(json, equalTo("{\"name\":\"Dominic\",\"age\":39,\"address\":{\"addressLines\":[\"13 Rue Morgue\",\"PO3 1TP\"]}}"));
}
@Test public void
writes_list_of_people_as_json() {
String json = ListSerialiser.writingItemsWith(Person.serialiser).toString(asList(
$$(
Person.name.of("Dominic"),
Person.age.of(39),
Person.favouriteColour.of(Color.RED),
Person.address.of(Address.addressLines.of("13 Rue Morgue", "PO3 1TP"))),
$$(
Person.name.of("Oliver"),
Person.age.of(14),
Person.favouriteColour.of(Color.BLACK),
Person.address.of(Address.addressLines.of("22 Acacia Avenue", "VB6 5UX"))
)));
assertThat(json, equalTo("[{\"name\":\"Dominic\",\"age\":39,\"favourite colour\":\"0xFF0000\",\"address\":{\"addressLines\":[\"13 Rue Morgue\",\"PO3 1TP\"]}}," +
"{\"name\":\"Oliver\",\"age\":14,\"favourite colour\":\"0x000000\",\"address\":{\"addressLines\":[\"22 Acacia Avenue\",\"VB6 5UX\"]}}]"));
}
@Test public void
writes_list_of_maps_of_lists_of_ints_as_json() {
Map<String, List<Integer>> map1 = new LinkedHashMap<>();
map1.put("primes", asList(1,2,3,5,7));
map1.put("evens", asList(2,4,6,8,10));
Map<String, List<Integer>> map2 = new LinkedHashMap<>();
map2.put("odds", asList(1,3,5,7,9));
map2.put("powers", asList(2,4,8,16,32));
List<Map<String, List<Integer>>> data = asList(map1, map2);
String json = ListSerialiser.writingItemsWith(
MapSerialiser.writingValuesWith(
ListSerialiser.writingItemsWith(toInteger)))
.toString(data);
assertThat(json, equalTo("[{\"primes\":[1,2,3,5,7],\"evens\":[2,4,6,8,10]},{\"odds\":[1,3,5,7,9],\"powers\":[2,4,8,16,32]}]"));
}
@Test public void
reflective_serialisation_works_too() throws JsonProcessingException {
Record me = $$(
Person.name.of("Dominic"),
Person.age.of(39),
Person.favouriteColour.of(Color.RED),
Person.address.of(Address.addressLines.of("13 Rue Morgue", "PO3 1TP")));
ObjectMapper mapper = ReflectiveRecordSerialiser.mapperWith(new ColorJsonSerializer());
String json = mapper.writeValueAsString(me);
Record meToo = Person.deserialiser.fromString(json);
assertThat(meToo, equalTo(me));
}
@Test public void
reflectively_serialise_multiple_records() throws JsonProcessingException {
Record me = $$(
Person.name.of("Dominic"),
Person.age.of(39),
Person.favouriteColour.of(Color.RED),
Person.address.of(Address.addressLines.of("13 Rue Morgue", "PO3 1TP")));
Record you = $$(
Person.name.of("Doppelganger"),
Person.age.of(40),
Person.favouriteColour.of(Color.BLUE),
Person.address.of(Address.addressLines.of("23 Acacia Avenue", "VB6 5UX")));
String json = ReflectiveRecordSerialiser.toJson(Stream.of(me, you), new ColorJsonSerializer());
List<Record> people = ListDeserialiser.readingItemsWith(Person.deserialiser).fromString(json);
assertThat(people, equalTo(Arrays.asList(me, you)));
}
private static class ColorJsonSerializer extends JsonSerializer<Color> {
@Override
public Class handledType() { return Color.class; }
@Override
public void serialize(Color o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString(Person.colourToString.apply(o));
}
}
}