/**
* 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.JsonSchema;
import com.turn.shapeshifter.ShapeshifterProtos.JsonType;
import com.turn.shapeshifter.testing.TestProtos.DefaultValue;
import com.turn.shapeshifter.testing.TestProtos.RequiredValue;
import com.turn.shapeshifter.testing.TestProtos.Union;
import com.turn.shapeshifter.transformers.DateTimeTransformer;
import java.util.Map;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.TextNode;
import com.google.common.base.CaseFormat;
import com.google.common.base.Preconditions;
import com.google.common.collect.Maps;
import org.junit.Assert;
import org.junit.Test;
/**
* Tests for {@link NamedSchema}.
*
* @author jsilland
*/
public class NamedSchemaTest {
public static final class ToString implements Transformer {
@Override
public JsonNode serialize(Object value) {
return new TextNode(value.toString());
}
@Override
public Object parse(JsonNode node) {
Preconditions.checkArgument(node.asToken().equals(JsonToken.VALUE_STRING));
String nodeValue = node.asText();
Integer value = Integer.valueOf(nodeValue);
return value;
}
@Override
public JsonType getJsonType() {
return JsonType.STRING;
}
};
@Test
public void testSchemaName() {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
Assert.assertEquals("Union", schema.getName());
}
@Test
public void testPropertyType() {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
Assert.assertEquals(JsonType.STRING, schema.getPropertyType("string_value"));
Assert.assertEquals(JsonType.INTEGER, schema.getPropertyType("int32_value"));
Assert.assertEquals(JsonType.INTEGER, schema.getPropertyType("int64_value"));
Assert.assertEquals(JsonType.BOOLEAN, schema.getPropertyType("bool_value"));
Assert.assertEquals(JsonType.OBJECT, schema.getPropertyType("union_value"));
Assert.assertEquals(JsonType.ARRAY, schema.getPropertyType("union_repeated"));
Assert.assertEquals(JsonType.ARRAY, schema.getPropertyType("int32_repeated"));
Assert.assertEquals(JsonType.STRING, schema.getPropertyType("enum_value"));
}
@Test
public void testPropertyName() {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
Assert.assertEquals("stringValue", schema.getPropertyName("string_value"));
}
@Test
public void testJsonSchemaEmptyRegistry() throws JsonSchemaException {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
try {
schema.getJsonSchema(ReadableSchemaRegistry.EMPTY);
Assert.fail();
} catch (IllegalArgumentException iae) {
// expected
}
}
@Test
public void testJsonSchemaSelfReference() throws JsonSchemaException {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
try {
schema.getJsonSchema(registry);
Assert.fail();
} catch (JsonSchemaException jse) {
// expected
}
}
@Test(expected = NullPointerException.class)
public void testJsonSchemasNullRegistry() throws JsonSchemaException {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
schema.getJsonSchema(null);
}
@Test
public void testJsonSchema() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
Assert.assertEquals(11, jsonSchema.getPropertiesCount());
Map<String, JsonSchema> properties = Maps.newHashMap();
for (JsonSchema property : jsonSchema.getPropertiesList()) {
properties.put(property.getName(), property);
}
Assert.assertTrue(properties.containsKey("stringValue"));
Assert.assertTrue(properties.containsKey("int32Value"));
Assert.assertTrue(properties.containsKey("int64Value"));
Assert.assertTrue(properties.containsKey("boolValue"));
Assert.assertTrue(properties.containsKey("unionValue"));
Assert.assertTrue(properties.containsKey("unionRepeated"));
Assert.assertTrue(properties.containsKey("int32Repeated"));
Assert.assertTrue(properties.containsKey("enumValue"));
Assert.assertEquals(JsonType.STRING, properties.get("stringValue").getType());
Assert.assertEquals(JsonType.INTEGER, properties.get("int32Value").getType());
Assert.assertEquals(JsonType.INTEGER, properties.get("int64Value").getType());
Assert.assertEquals(JsonType.BOOLEAN, properties.get("boolValue").getType());
Assert.assertEquals(JsonType.OBJECT, properties.get("unionValue").getType());
Assert.assertEquals(JsonType.ARRAY, properties.get("unionRepeated").getType());
Assert.assertEquals(JsonType.ARRAY, properties.get("int32Repeated").getType());
Assert.assertEquals(JsonType.STRING, properties.get("enumValue").getType());
Assert.assertEquals(JsonType.OBJECT, properties.get("unionRepeated").getItems().getType());
Assert.assertEquals(JsonType.INTEGER, properties.get("int32Repeated").getItems().getType());
Assert.assertEquals("Union",
properties.get("unionRepeated").getItems().getSchemaReference());
Assert.assertEquals(2, properties.get("enumValue").getEnumList().size());
Assert.assertTrue(properties.get("enumValue").getEnumList().contains("first"));
Assert.assertTrue(properties.get("enumValue").getEnumList().contains("second"));
}
@Test
public void testJsonSchemaWithTransform() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.transform("int32_value", new ToString())
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("int32Value")) {
Assert.assertEquals(JsonType.STRING, property.getType());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithSkippedField() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.skip("int32_value")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
Assert.assertEquals(10, jsonSchema.getPropertiesCount());
}
@Test
public void testJsonSchemaWithConstant() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.addConstant("key", "value")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
Assert.assertEquals(12, jsonSchema.getPropertiesCount());
}
@Test
public void testJsonSchemaWithSubstitution() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.substitute("string_value", "foobar")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
Assert.assertFalse(property.getName().equals("stringValue"));
if (property.getName().equals("foobar")) {
Assert.assertEquals(JsonType.STRING, property.getType());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithMapping() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.mapRepeatedField("union_repeated", "string_value")
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("unionRepeated")) {
Assert.assertEquals(JsonType.OBJECT, property.getType());
Assert.assertEquals("Union",
property.getAdditionalProperties().getSchemaReference());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithEnumCaseFormat() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.enumCaseFormat(CaseFormat.UPPER_UNDERSCORE)
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("enumValue")) {
Assert.assertEquals(JsonType.STRING, property.getType());
Assert.assertTrue(property.getEnumList().contains("FIRST"));
Assert.assertTrue(property.getEnumList().contains("SECOND"));
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithFormatTransformer() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.transform("int64_value", new DateTimeTransformer())
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
Assert.assertEquals("Union", jsonSchema.getId());
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("int64Value")) {
Assert.assertEquals(JsonType.STRING, property.getType());
Assert.assertEquals("date-time", property.getFormat());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithDefaultValue() throws Exception {
NamedSchema schema = NamedSchema.of(DefaultValue.getDescriptor(), "DefaultValue");
JsonSchema jsonSchema = schema.getJsonSchema(SchemaRegistry.EMPTY);
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("stringValue")) {
Assert.assertEquals("foo", property.getDefault());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithDefaultValueEnumCaseFormat() throws Exception {
NamedSchema schema = NamedSchema.of(DefaultValue.getDescriptor(), "DefaultValue");
JsonSchema jsonSchema = schema.getJsonSchema(SchemaRegistry.EMPTY);
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("enumValue")) {
Assert.assertEquals(property.getDefault(), "second");
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithDefaultValueCustomEnumCaseFormat() throws Exception {
NamedSchema schema = NamedSchema.of(DefaultValue.getDescriptor(), "DefaultValue")
.enumCaseFormat(CaseFormat.UPPER_UNDERSCORE);
JsonSchema jsonSchema = schema.getJsonSchema(SchemaRegistry.EMPTY);
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("enumValue")) {
Assert.assertEquals(property.getDefault(), "SECOND");
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithRequiredField() throws Exception {
NamedSchema schema = NamedSchema.of(RequiredValue.getDescriptor(), "RequiredValue");
JsonSchema jsonSchema = schema.getJsonSchema(SchemaRegistry.EMPTY);
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("requiredString")) {
Assert.assertTrue(property.getRequired());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithFormat() throws Exception {
NamedSchema schema = NamedSchema.of(DefaultValue.getDescriptor(), "DefaultValue")
.setFormat("string_value", "int");
JsonSchema jsonSchema = schema.getJsonSchema(SchemaRegistry.EMPTY);
boolean checked = false;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("stringValue")) {
Assert.assertEquals("int", property.getFormat());
checked = true;
}
}
Assert.assertTrue(checked);
}
@Test
public void testJsonSchemaWithLongAsString() throws Exception {
NamedSchema schema = NamedSchema.of(Union.getDescriptor(), "Union")
.surfaceLongsAsStrings()
.useSchema("union_value", "Union")
.useSchema("union_repeated", "Union");
SchemaRegistry registry = new SchemaRegistry();
registry.register(schema);
JsonSchema jsonSchema = schema.getJsonSchema(registry);
int checks = 0;
for (JsonSchema property : jsonSchema.getPropertiesList()) {
if (property.getName().equals("int64Value")) {
Assert.assertEquals("int64", property.getFormat());
Assert.assertEquals(JsonType.STRING, property.getType());
checks++;
} else if (property.getName().equals("int64Repeated")) {
JsonSchema items = property.getItems();
Assert.assertEquals("int64", items.getFormat());
Assert.assertEquals(JsonType.STRING, items.getType());
checks++;
} else if (property.getName().equals("uint64Value")) {
Assert.assertEquals("uint64", property.getFormat());
Assert.assertEquals(JsonType.STRING, property.getType());
checks++;
}
}
Assert.assertEquals(3, checks);
}
}