/*
* Copyright (C) 2012 Facebook, 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.facebook.swift.codec.metadata;
import com.facebook.swift.codec.ThriftConstructor;
import com.facebook.swift.codec.ThriftField;
import com.facebook.swift.codec.ThriftStruct;
import com.google.common.reflect.TypeToken;
import org.testng.annotations.Test;
import java.lang.reflect.Type;
import java.util.concurrent.locks.Lock;
import static com.facebook.swift.codec.ThriftField.Requiredness;
import static org.fest.assertions.Assertions.assertThat;
public class TestThriftStructMetadataBuilder
{
@Test
public void testNoId()
throws Exception
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), NoId.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.hasSize(1);
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.isEmpty();
assertThat(metadataErrors.getErrors().get(0).getMessage())
.as("error message")
.containsIgnoringCase("not have an id");
}
@ThriftStruct
public final static class NoId
{
@ThriftField
public String getField1()
{
return null;
}
@ThriftField
public void setField1(String value)
{
}
}
@Test
public void testMultipleIds()
throws Exception
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), MultipleIds.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.hasSize(1);
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.isEmpty();
assertThat(metadataErrors.getErrors().get(0).getMessage())
.as("error message")
.containsIgnoringCase("multiple ids");
}
@ThriftStruct
public final static class MultipleIds
{
@ThriftField(name = "foo", value = 1)
public void setField1(String value)
{
}
@ThriftField(name = "foo", value = 2)
public void setField2(String value)
{
}
@ThriftField(name = "foo")
public String getField1()
{
return null;
}
@ThriftField(name = "foo")
public String getField2()
{
return null;
}
}
@Test
public void testMultipleNames()
throws Exception
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), MultipleNames.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.isEmpty();
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.hasSize(1);
assertThat(metadataErrors.getWarnings().get(0).getMessage())
.as("error message")
.containsIgnoringCase("multiple names");
}
@ThriftStruct
public final static class MultipleNames
{
@ThriftField(value = 1, name = "foo")
public String getFoo()
{
return null;
}
@ThriftField(value = 1, name = "bar")
public void setFoo(String value)
{
}
}
@Test
public void testUnsupportedType()
throws Exception
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), UnsupportedJavaType.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.hasSize(1);
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.isEmpty();
assertThat(metadataErrors.getErrors().get(0).getMessage())
.as("error message")
.containsIgnoringCase("not a supported Java type");
}
@ThriftStruct
public final static class UnsupportedJavaType
{
@ThriftField(1)
public Lock unsupportedJavaType;
}
@Test
public void testMultipleTypes()
throws Exception
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), MultipleTypes.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.hasSize(1);
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.isEmpty();
assertThat(metadataErrors.getErrors().get(0).getMessage())
.as("error message")
.containsIgnoringCase("multiple types");
}
@ThriftStruct
public final static class MultipleTypes
{
@ThriftField(1)
public int getFoo()
{
return 0;
}
@ThriftField
public void setFoo(short value)
{
}
}
@Test
public void testGenericBuilder()
{
Type structType = new TypeToken<GenericStruct<String>>() {}.getType();
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), structType);
builder.build();
}
@ThriftStruct(builder = GenericStruct.GenericBuilder.class)
public final static class GenericStruct<T>
{
private T fieldValue;
private GenericStruct(T fieldValue)
{
this.fieldValue = fieldValue;
}
@ThriftField(1)
public T getFieldValue()
{
return fieldValue;
}
public static class GenericBuilder<T>
{
private T fieldValue;
@ThriftField(1)
public GenericBuilder<T> setFieldValue(T fieldValue)
{
this.fieldValue = fieldValue;
return this;
}
@ThriftConstructor
public GenericStruct<T> build()
{
return new GenericStruct<>(fieldValue);
}
}
}
@Test(expectedExceptions = { MetadataErrorException.class })
public void testGenericBuilderForNonGenericStruct()
{
Type structType = new TypeToken<NonGenericStruct>() {}.getType();
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), structType);
builder.build();
}
@ThriftStruct(builder = NonGenericStruct.GenericBuilder.class)
public static class NonGenericStruct
{
private NonGenericStruct()
{
}
public static class GenericBuilder<T>
{
@ThriftConstructor
public NonGenericStruct build()
{
return new NonGenericStruct();
}
}
}
@Test
public void testMulitpleRequiredness()
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), MultipleRequiredness.class);
MetadataErrors metadataErrors = builder.getMetadataErrors();
assertThat(metadataErrors.getErrors())
.as("metadata errors")
.hasSize(1);
assertThat(metadataErrors.getWarnings())
.as("metadata warnings")
.isEmpty();
assertThat(metadataErrors.getErrors().get(0).getMessage())
.as("error message")
.containsIgnoringCase("multiple requiredness");
}
@ThriftStruct
public static final class MultipleRequiredness
{
@ThriftField(value = 1, requiredness = Requiredness.OPTIONAL)
public int getFoo()
{
return 0;
}
@ThriftField(value = 1, requiredness = Requiredness.NONE)
public void setFoo(int value)
{
}
}
@Test
public void testMergeableRequiredness()
{
ThriftStructMetadata metadata = new ThriftStructMetadataBuilder(new ThriftCatalog(), MergeableRequiredness.class).build();
assertThat(metadata.getField(1).getRequiredness())
.as("requiredness of field 'foo'")
.isEqualTo(Requiredness.OPTIONAL);
}
@ThriftStruct
public static final class MergeableRequiredness
{
@ThriftField(value = 1, requiredness = Requiredness.OPTIONAL)
public int getFoo()
{
return 0;
}
@ThriftField
public void setFoo(int value)
{
}
}
@Test
public void testNonFinalStructsOk()
{
ThriftStructMetadataBuilder builder = new ThriftStructMetadataBuilder(new ThriftCatalog(), NotFinalStruct.class);
builder.build();
}
@ThriftStruct
public static class NotFinalStruct
{
}
}