com.turn.shapeshifter.NamedSchemaSerializerTest.java Source code

Java tutorial

Introduction

Here is the source code for com.turn.shapeshifter.NamedSchemaSerializerTest.java

Source

/**
 * Copyright 2012, 2013 Turn, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.turn.shapeshifter;

import com.turn.shapeshifter.ShapeshifterProtos.JsonType;
import com.turn.shapeshifter.testing.TestProtos.Actor;
import com.turn.shapeshifter.testing.TestProtos.DefaultValue;
import com.turn.shapeshifter.testing.TestProtos.Movie;
import com.turn.shapeshifter.testing.TestProtos.SomeEnum;
import com.turn.shapeshifter.testing.TestProtos.Union;
import com.turn.shapeshifter.transformers.DateTimeTransformer;

import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.IntNode;
import com.google.common.base.CaseFormat;
import com.google.common.base.Preconditions;
import com.google.protobuf.ByteString;

import org.junit.Assert;
import org.junit.Test;

/**
 * Tests for {@link NamedSchemaSerializer}.
 * 
 * @author jsilland
 */
public class NamedSchemaSerializerTest {

    private static final Transformer TWO = new Transformer() {

        @Override
        public JsonType getJsonType() {
            return JsonType.INTEGER;
        }

        @Override
        public JsonNode serialize(Object value) {
            Preconditions.checkArgument(value instanceof Integer);
            Integer integer = (Integer) value;
            return new IntNode(integer * 2);
        }

        @Override
        public Object parse(JsonNode node) {
            Preconditions.checkArgument(JsonToken.VALUE_NUMBER_INT.equals(node.asToken()));
            int value = node.asInt();
            return new Integer(value / 2);
        }
    };

    @Test
    public void testSerialize() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").addConstant("kind",
                "shapeshifter.Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setBoolValue(true).setEnumValue(SomeEnum.FIRST).setInt32Value(42)
                .setInt64Value(42L).setStringValue("text").build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);

        Assert.assertTrue(result.isObject());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("kind").asToken());
        Assert.assertEquals("shapeshifter.Union", result.get("kind").asText());
        Assert.assertEquals(JsonToken.VALUE_TRUE, result.get("boolValue").asToken());
        Assert.assertEquals(true, result.get("boolValue").asBoolean());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("enumValue").asToken());
        Assert.assertEquals("first", result.get("enumValue").asText());
        Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, result.get("int32Value").asToken());
        Assert.assertEquals(42, result.get("int32Value").asInt());
        Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, result.get("int64Value").asToken());
        Assert.assertEquals(42, result.get("int64Value").asInt());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("stringValue").asToken());
        Assert.assertEquals("text", result.get("stringValue").asText());
    }

    @Test
    public void testSerializeWithSubObject() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").addConstant("kind", "Union")
                .useSchema("union_value", "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union subUnion = Union.newBuilder().setInt32Value(42).build();
        Union union = Union.newBuilder().setEnumValue(SomeEnum.SECOND).setUnionValue(subUnion).build();

        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("kind").asToken());
        Assert.assertEquals("Union", result.get("kind").asText());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("enumValue").asToken());
        Assert.assertEquals("second", result.get("enumValue").asText());

        JsonNode subUnionJson = result.get("unionValue");
        Assert.assertTrue(subUnionJson.isObject());
        Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, subUnionJson.get("int32Value").asToken());
        Assert.assertEquals(42, subUnionJson.get("int32Value").asInt());
        Assert.assertEquals(JsonToken.VALUE_STRING, subUnionJson.get("kind").asToken());
        Assert.assertEquals("Union", subUnionJson.get("kind").asText());
    }

    @Test
    public void testSerializeWithEmptyObject() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.getDefaultInstance();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertTrue(result.isNull());
    }

    @Test
    public void testSerializeWithEmptySubObject() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setBoolValue(true).build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals(1, result.size());
        Assert.assertNull(result.get("unionValue"));
    }

    @Test
    public void testSerializeWithRepeatedObject() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").useSchema("union_repeated", "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union subUnion = Union.newBuilder().setInt32Value(42).build();
        Union union = Union.newBuilder().addUnionRepeated(subUnion).addUnionRepeated(subUnion).build();

        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        JsonNode array = result.get("unionRepeated");
        Assert.assertTrue(array.isArray());
        Assert.assertEquals(2, array.size());
        for (JsonNode item : array) {
            Assert.assertTrue(item.isObject());
            Assert.assertEquals(42, item.get("int32Value").intValue());
        }
    }

    @Test
    public void testSerializeWithRepeatedPrimitive() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().addInt32Repeated(42).addInt32Repeated(42).build();

        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        JsonNode array = result.get("int32Repeated");
        Assert.assertTrue(array.isArray());
        Assert.assertEquals(2, array.size());
        for (JsonNode item : array) {
            Assert.assertEquals(JsonToken.VALUE_NUMBER_INT, item.asToken());
            Assert.assertEquals(42, item.intValue());
        }
    }

    @Test
    public void testSerializeWithEmptyRepeated() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").useSchema("union_repeated", "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setBoolValue(true).addUnionRepeated(Union.getDefaultInstance()).build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals(1, result.size());
        Assert.assertEquals(JsonToken.VALUE_TRUE, result.get("boolValue").asToken());
        Assert.assertEquals(true, result.get("boolValue").asBoolean());
        Assert.assertNull(result.get("unionRepeated"));
    }

    @Test
    public void testSerializeMessageWithDefaultValue() throws Exception {
        // This test ensures that we do not serialize default values when they haven't
        // been explicitly set. This mirrors the behavior of protocol buffers
        // themselves.
        NamedSchema schema = NamedSchema.of(DefaultValue.getDescriptor(), "Union");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        DefaultValue defaultValue = DefaultValue.newBuilder().build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(defaultValue, registry);
        Assert.assertTrue(result.isNull());
    }

    @Test
    public void testSerializeCustomEnumFormat() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
                .enumCaseFormat(CaseFormat.UPPER_UNDERSCORE);
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setEnumValue(SomeEnum.FIRST).build();

        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertEquals("FIRST", result.get("enumValue").asText());
    }

    @Test
    public void testSerializeSubtitution() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").substitute("string_value", "$ref");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setStringValue("foo").build();

        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertNotNull(result.get("$ref"));
    }

    @Test
    public void testSerializeWithTransform() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").transform("int64_value",
                new DateTimeTransformer());
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union union = Union.newBuilder().setInt64Value(1234567890000L).build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(union, registry);
        Assert.assertEquals("2009-02-13T23:31:30.000Z", result.get("int64Value").asText());
    }

    @Test
    public void testSerializeWithRepeatedTransform() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").transform("int32_repeated", TWO);
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        Union fibonacci = Union.newBuilder().addInt32Repeated(1).addInt32Repeated(1).addInt32Repeated(2)
                .addInt32Repeated(3).addInt32Repeated(5).addInt32Repeated(8).build();
        JsonNode result = new NamedSchemaSerializer(schema).serialize(fibonacci, registry);
        Assert.assertTrue(result.isObject());
        ArrayNode array = (ArrayNode) result.get("int32Repeated");
        Assert.assertEquals(2, array.get(0).asInt());
        Assert.assertEquals(2, array.get(1).asInt());
        Assert.assertEquals(4, array.get(2).asInt());
        Assert.assertEquals(6, array.get(3).asInt());
        Assert.assertEquals(10, array.get(4).asInt());
        Assert.assertEquals(16, array.get(5).asInt());
    }

    @Test
    public void testSerializeMappings() throws Exception {
        Movie bladeRunner = Movie.newBuilder().setYear(1981).setTitle("Blade Runner").build();
        Movie starWars = Movie.newBuilder().setYear(1978).setTitle("Star Wars").build();
        Actor actor = Actor.newBuilder().addMovies(bladeRunner).addMovies(starWars).setName("Harrison Ford")
                .build();

        NamedSchema schema = NamedSchema.of(Actor.getDescriptor(), "Actor").mapRepeatedField("movies", "title");
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        JsonNode result = new NamedSchemaSerializer(schema).serialize(actor, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals("Harrison Ford", result.get("name").asText());
        JsonNode movies = result.get("movies");
        Assert.assertTrue(movies.isObject());
        Assert.assertNotNull(movies.get("Blade Runner"));
        Assert.assertEquals(1981, movies.get("Blade Runner").get("year").asInt());
        Assert.assertNotNull(movies.get("Star Wars"));
        Assert.assertEquals(1978, movies.get("Star Wars").get("year").asInt());
    }

    @Test
    public void testLongAsString() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").surfaceLongsAsStrings()
                .useSchema("union_value", "Union").useSchema("union_repeated", "Union");

        Union union = Union.newBuilder().setInt64Value(1234567890L).addInt64Repeated(1234567L).build();
        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        JsonNode result = schema.getSerializer().serialize(union, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("int64Value").asToken());
        Assert.assertEquals("1234567890", result.get("int64Value").asText());
        JsonNode arrayItem = result.get("int64Repeated").get(0);
        Assert.assertEquals(JsonToken.VALUE_STRING, arrayItem.asToken());
        Assert.assertEquals("1234567", arrayItem.asText());
    }

    @Test
    public void testSerializeBytes() throws Exception {
        NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union").surfaceLongsAsStrings()
                .setFormat("bytes_value", "byte");

        byte[] bytes = new byte[] { (byte) 0xe0, 0x4f, (byte) 0xd0, 0x20, (byte) 0xea, 0x3a, 0x69, 0x10,
                (byte) 0xa2, (byte) 0xd8, 0x08, 0x00, 0x2b, 0x30, 0x30, (byte) 0x9d };
        Union union = Union.newBuilder().setBytesValue(ByteString.copyFrom(bytes)).build();

        SchemaRegistry registry = new SchemaRegistry();
        registry.register(schema);
        JsonNode result = schema.getSerializer().serialize(union, registry);
        Assert.assertTrue(result.isObject());
        Assert.assertEquals(JsonToken.VALUE_STRING, result.get("bytesValue").asToken());
        Assert.assertEquals(bytes.length, result.get("bytesValue").asText().length());
        for (int i = 0; i < bytes.length; i++) {
            if (bytes[i] != (byte) result.get("bytesValue").asText().charAt(i)) {
                Assert.fail("bytes value has been interpolated!");
            }
        }
    }
}