blob: 1f069abf237297736928ca97d0edf1225c0231a6 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.apache.avro.compiler.specific;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertThat;
import static org.hamcrest.CoreMatchers.not;
import static org.hamcrest.CoreMatchers.equalTo;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.apache.avro.AvroTestUtil;
import org.apache.avro.LogicalTypes;
import org.apache.avro.Schema;
import org.apache.avro.SchemaBuilder;
import org.apache.avro.generic.GenericData.StringType;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.tools.Diagnostic;
import javax.tools.DiagnosticListener;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
@RunWith(JUnit4.class)
public class TestSpecificCompiler {
private static final Logger LOG = LoggerFactory.getLogger(TestSpecificCompiler.class);
private final String schemaSrcPath = "src/test/resources/simple_record.avsc";
private final String velocityTemplateDir =
"src/main/velocity/org/apache/avro/compiler/specific/templates/java/classic/";
private File src;
private File outputDir;
private File outputFile;
@Before
public void setUp() {
this.src = new File(this.schemaSrcPath);
this.outputDir = AvroTestUtil.tempDirectory(getClass(), "specific-output");
this.outputFile = new File(this.outputDir, "SimpleRecord.java");
if (outputFile.exists() && !outputFile.delete()) {
throw new IllegalStateException("unable to delete " + outputFile);
}
}
@After
public void tearDow() {
if (this.outputFile != null) {
this.outputFile.delete();
}
}
/** Uses the system's java compiler to actually compile the generated code. */
static void assertCompilesWithJavaCompiler(Collection<SpecificCompiler.OutputFile> outputs)
throws IOException {
if (outputs.isEmpty())
return; // Nothing to compile!
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager =
compiler.getStandardFileManager(null, null, null);
File dstDir = AvroTestUtil.tempFile(TestSpecificCompiler.class, "realCompiler");
List<File> javaFiles = new ArrayList<File>();
for (SpecificCompiler.OutputFile o : outputs) {
javaFiles.add(o.writeToDestination(null, dstDir));
}
final List<Diagnostic<?>> warnings = new ArrayList<Diagnostic<?>>();
DiagnosticListener<JavaFileObject> diagnosticListener = new DiagnosticListener<JavaFileObject>() {
@Override
public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
switch (diagnostic.getKind()) {
case ERROR:
// Do not add these to warnings becuase they will fail the compile, anyway.
LOG.error("{}", diagnostic);
break;
case WARNING:
case MANDATORY_WARNING:
LOG.warn("{}", diagnostic);
warnings.add(diagnostic);
break;
case NOTE:
case OTHER:
LOG.debug("{}", diagnostic);
break;
}
}
};
JavaCompiler.CompilationTask cTask = compiler.getTask(null, fileManager,
diagnosticListener, Collections.singletonList("-Xlint:all"), null,
fileManager.getJavaFileObjects(javaFiles.toArray(new File[javaFiles.size()])));
boolean compilesWithoutError = cTask.call();
assertTrue(compilesWithoutError);
assertEquals("Warnings produced when compiling generated code with -Xlint:all", 0, warnings.size());
}
private static Schema createSampleRecordSchema(int numStringFields, int numDoubleFields) {
SchemaBuilder.FieldAssembler<Schema> sb = SchemaBuilder.record("sample.record").fields();
for (int i = 0; i < numStringFields; i++) {
sb.name("sf_" + i).type().stringType().noDefault();
}
for (int i = 0; i < numDoubleFields; i++) {
sb.name("df_" + i).type().doubleType().noDefault();
}
return sb.endRecord();
}
private SpecificCompiler createCompiler() throws IOException {
Schema.Parser parser = new Schema.Parser();
Schema schema = parser.parse(this.src);
SpecificCompiler compiler = new SpecificCompiler(schema);
compiler.setTemplateDir(this.velocityTemplateDir);
compiler.setStringType(StringType.CharSequence);
return compiler;
}
@Test
public void testCanReadTemplateFilesOnTheFilesystem() throws IOException, URISyntaxException{
SpecificCompiler compiler = createCompiler();
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
}
@Test
public void testPublicFieldVisibility() throws IOException {
SpecificCompiler compiler = createCompiler();
compiler.setFieldVisibility(SpecificCompiler.FieldVisibility.PUBLIC);
assertFalse(compiler.deprecatedFields());
assertTrue(compiler.publicFields());
assertFalse(compiler.privateFields());
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
String line = null;
while ((line = reader.readLine()) != null) {
// No line, once trimmed, should start with a deprecated field declaration
// nor a private field declaration. Since the nested builder uses private
// fields, we cannot do the second check.
line = line.trim();
assertFalse("Line started with a deprecated field declaration: " + line,
line.startsWith("@Deprecated public int value"));
}
reader.close();
}
@Test
public void testCreateAllArgsConstructor() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
String line = null;
boolean foundAllArgsConstructor = false;
while (!foundAllArgsConstructor && (line = reader.readLine()) != null) {
foundAllArgsConstructor = line.contains("All-args constructor");
}
reader.close();
assertTrue(foundAllArgsConstructor);
}
@Test
public void testMaxValidParameterCounts() throws Exception {
Schema validSchema1 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT, 0);
assertCompilesWithJavaCompiler(new SpecificCompiler(validSchema1).compile());
Schema validSchema2 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT - 2, 1);
assertCompilesWithJavaCompiler(new SpecificCompiler(validSchema1).compile());
}
@Test
public void testInvalidParameterCounts() throws Exception {
Schema invalidSchema1 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT + 1, 0);
SpecificCompiler compiler = new SpecificCompiler(invalidSchema1);
assertCompilesWithJavaCompiler(compiler.compile());
Schema invalidSchema2 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT, 10);
compiler = new SpecificCompiler(invalidSchema2);
assertCompilesWithJavaCompiler(compiler.compile());
}
@Test
public void testMaxParameterCounts() throws Exception {
Schema validSchema1 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT, 0);
assertTrue(new SpecificCompiler(validSchema1).compile().size() > 0);
Schema validSchema2 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT - 2, 1);
assertTrue(new SpecificCompiler(validSchema2).compile().size() > 0);
Schema validSchema3 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT - 1, 1);
assertTrue(new SpecificCompiler(validSchema3).compile().size() > 0);
Schema validSchema4 = createSampleRecordSchema(SpecificCompiler.MAX_FIELD_PARAMETER_UNIT_COUNT + 1, 0);
assertTrue(new SpecificCompiler(validSchema4).compile().size() > 0);
}
@Test(expected=RuntimeException.class)
public void testCalcAllArgConstructorParameterUnitsFailure() {
Schema nonRecordSchema = SchemaBuilder.array().items().booleanType();
new SpecificCompiler().calcAllArgConstructorParameterUnits(nonRecordSchema);
}
@Test
public void testPublicDeprecatedFieldVisibility() throws IOException {
SpecificCompiler compiler = createCompiler();
assertTrue(compiler.deprecatedFields());
assertTrue(compiler.publicFields());
assertFalse(compiler.privateFields());
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
String line = null;
while ((line = reader.readLine()) != null) {
// No line, once trimmed, should start with a public field declaration
line = line.trim();
assertFalse("Line started with a public field declaration: " + line,
line.startsWith("public int value"));
}
reader.close();
}
@Test
public void testPrivateFieldVisibility() throws IOException {
SpecificCompiler compiler = createCompiler();
compiler.setFieldVisibility(SpecificCompiler.FieldVisibility.PRIVATE);
assertFalse(compiler.deprecatedFields());
assertFalse(compiler.publicFields());
assertTrue(compiler.privateFields());
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
String line = null;
while ((line = reader.readLine()) != null) {
// No line, once trimmed, should start with a public field declaration
// or with a deprecated public field declaration
line = line.trim();
assertFalse("Line started with a public field declaration: " + line,
line.startsWith("public int value"));
assertFalse("Line started with a deprecated field declaration: " + line,
line.startsWith("@Deprecated public int value"));
}
reader.close();
}
@Test
public void testSettersCreatedByDefault() throws IOException {
SpecificCompiler compiler = createCompiler();
assertTrue(compiler.isCreateSetters());
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
int foundSetters = 0;
String line = null;
while ((line = reader.readLine()) != null) {
// We should find the setter in the main class
line = line.trim();
if (line.startsWith("public void setValue(")) {
foundSetters++;
}
}
reader.close();
assertEquals("Found the wrong number of setters", 1, foundSetters);
}
@Test
public void testSettersNotCreatedWhenOptionTurnedOff() throws IOException {
SpecificCompiler compiler = createCompiler();
compiler.setCreateSetters(false);
assertFalse(compiler.isCreateSetters());
compiler.compileToDestination(this.src, this.outputDir);
assertTrue(this.outputFile.exists());
BufferedReader reader = new BufferedReader(new FileReader(this.outputFile));
String line = null;
while ((line = reader.readLine()) != null) {
// No setter should be found
line = line.trim();
assertFalse("No line should include the setter: " + line,
line.startsWith("public void setValue("));
}
reader.close();
}
@Test
public void testSettingOutputCharacterEncoding() throws Exception {
SpecificCompiler compiler = createCompiler();
// Generated file in default encoding
compiler.compileToDestination(this.src, this.outputDir);
byte[] fileInDefaultEncoding = new byte[(int) this.outputFile.length()];
FileInputStream is = new FileInputStream(this.outputFile);
is.read(fileInDefaultEncoding);
is.close(); //close input stream otherwise delete might fail
if (!this.outputFile.delete()) {
throw new IllegalStateException("unable to delete " + this.outputFile); //delete otherwise compiler might not overwrite because src timestamp hasnt changed.
}
// Generate file in another encoding (make sure it has different number of bytes per character)
String differentEncoding = Charset.defaultCharset().equals(Charset.forName("UTF-16")) ? "UTF-32" : "UTF-16";
compiler.setOutputCharacterEncoding(differentEncoding);
compiler.compileToDestination(this.src, this.outputDir);
byte[] fileInDifferentEncoding = new byte[(int) this.outputFile.length()];
is = new FileInputStream(this.outputFile);
is.read(fileInDifferentEncoding);
is.close();
// Compare as bytes
assertThat("Generated file should contain different bytes after setting non-default encoding",
fileInDefaultEncoding, not(equalTo(fileInDifferentEncoding)));
// Compare as strings
assertThat("Generated files should contain the same characters in the proper encodings",
new String(fileInDefaultEncoding), equalTo(new String(fileInDifferentEncoding, differentEncoding)));
}
@Test
public void testJavaTypeWithDecimalLogicalTypeEnabled() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(true);
Schema dateSchema = LogicalTypes.date()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeSchema = LogicalTypes.timeMillis()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timestampSchema = LogicalTypes.timestampMillis()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema decimalSchema = LogicalTypes.decimal(9,2)
.addToSchema(Schema.create(Schema.Type.BYTES));
Schema uuidSchema = LogicalTypes.uuid()
.addToSchema(Schema.create(Schema.Type.STRING));
// Date/time types should always use upper level java classes
// Decimal type target class depends on configuration
// UUID should always be CharSequence since we haven't added its
// support in SpecificRecord
Assert.assertEquals("Should use Joda LocalDate for date type",
"org.joda.time.LocalDate", compiler.javaType(dateSchema));
Assert.assertEquals("Should use Joda LocalTime for time-millis type",
"org.joda.time.LocalTime", compiler.javaType(timeSchema));
Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
"org.joda.time.DateTime", compiler.javaType(timestampSchema));
Assert.assertEquals("Should use Java BigDecimal type",
"java.math.BigDecimal", compiler.javaType(decimalSchema));
Assert.assertEquals("Should use Java CharSequence type",
"java.lang.CharSequence", compiler.javaType(uuidSchema));
}
@Test
public void testJavaTypeWithDecimalLogicalTypeDisabled() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(false);
Schema dateSchema = LogicalTypes.date()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeSchema = LogicalTypes.timeMillis()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timestampSchema = LogicalTypes.timestampMillis()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema decimalSchema = LogicalTypes.decimal(9,2)
.addToSchema(Schema.create(Schema.Type.BYTES));
Schema uuidSchema = LogicalTypes.uuid()
.addToSchema(Schema.create(Schema.Type.STRING));
// Date/time types should always use upper level java classes
// Decimal type target class depends on configuration
// UUID should always be CharSequence since we haven't added its
// support in SpecificRecord
Assert.assertEquals("Should use Joda LocalDate for date type",
"org.joda.time.LocalDate", compiler.javaType(dateSchema));
Assert.assertEquals("Should use Joda LocalTime for time-millis type",
"org.joda.time.LocalTime", compiler.javaType(timeSchema));
Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
"org.joda.time.DateTime", compiler.javaType(timestampSchema));
Assert.assertEquals("Should use ByteBuffer type",
"java.nio.ByteBuffer", compiler.javaType(decimalSchema));
Assert.assertEquals("Should use Java CharSequence type",
"java.lang.CharSequence", compiler.javaType(uuidSchema));
}
@Test
public void testJavaUnbox() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(false);
Schema intSchema = Schema.create(Schema.Type.INT);
Schema longSchema = Schema.create(Schema.Type.LONG);
Schema floatSchema = Schema.create(Schema.Type.FLOAT);
Schema doubleSchema = Schema.create(Schema.Type.DOUBLE);
Schema boolSchema = Schema.create(Schema.Type.BOOLEAN);
Assert.assertEquals("Should use int for Type.INT",
"int", compiler.javaUnbox(intSchema));
Assert.assertEquals("Should use long for Type.LONG",
"long", compiler.javaUnbox(longSchema));
Assert.assertEquals("Should use float for Type.FLOAT",
"float", compiler.javaUnbox(floatSchema));
Assert.assertEquals("Should use double for Type.DOUBLE",
"double", compiler.javaUnbox(doubleSchema));
Assert.assertEquals("Should use boolean for Type.BOOLEAN",
"boolean", compiler.javaUnbox(boolSchema));
Schema dateSchema = LogicalTypes.date()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeSchema = LogicalTypes.timeMillis()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeMicroSchema = LogicalTypes.timeMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampSchema = LogicalTypes.timestampMillis()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampMicrosSchema = LogicalTypes.timestampMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
// Date/time types should always use upper level java classes, even though
// their underlying representations are primitive types
Assert.assertEquals("Should use Joda LocalDate for date type",
"org.joda.time.LocalDate", compiler.javaUnbox(dateSchema));
Assert.assertEquals("Should use Joda LocalTime for time-millis type",
"org.joda.time.LocalTime", compiler.javaUnbox(timeSchema));
Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
"org.joda.time.DateTime", compiler.javaUnbox(timestampSchema));
Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
"org.joda.time.LocalTime", compiler.javaUnbox(timeMicroSchema));
Assert.assertEquals("Should use Joda DateTime for timestamp-millis type",
"org.joda.time.DateTime", compiler.javaUnbox(timestampMicrosSchema));
}
@Test
public void testNullableTypesJavaUnbox() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(false);
// Nullable types should return boxed types instead of primitive types
Schema nullableIntSchema1 = Schema.createUnion(
Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.INT));
Schema nullableIntSchema2 = Schema.createUnion(
Schema.create(Schema.Type.INT), Schema.create(Schema.Type.NULL));
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableIntSchema1), "java.lang.Integer");
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableIntSchema2), "java.lang.Integer");
Schema nullableLongSchema1 = Schema.createUnion(
Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.LONG));
Schema nullableLongSchema2 = Schema.createUnion(
Schema.create(Schema.Type.LONG), Schema.create(Schema.Type.NULL));
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableLongSchema1), "java.lang.Long");
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableLongSchema2), "java.lang.Long");
Schema nullableFloatSchema1 = Schema.createUnion(
Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.FLOAT));
Schema nullableFloatSchema2 = Schema.createUnion(
Schema.create(Schema.Type.FLOAT), Schema.create(Schema.Type.NULL));
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableFloatSchema1), "java.lang.Float");
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableFloatSchema2), "java.lang.Float");
Schema nullableDoubleSchema1 = Schema.createUnion(
Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.DOUBLE));
Schema nullableDoubleSchema2 = Schema.createUnion(
Schema.create(Schema.Type.DOUBLE), Schema.create(Schema.Type.NULL));
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableDoubleSchema1), "java.lang.Double");
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableDoubleSchema2), "java.lang.Double");
Schema nullableBooleanSchema1 = Schema.createUnion(
Schema.create(Schema.Type.NULL), Schema.create(Schema.Type.BOOLEAN));
Schema nullableBooleanSchema2 = Schema.createUnion(
Schema.create(Schema.Type.BOOLEAN), Schema.create(Schema.Type.NULL));
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableBooleanSchema1), "java.lang.Boolean");
Assert.assertEquals("Should return boxed type",
compiler.javaUnbox(nullableBooleanSchema2), "java.lang.Boolean");
}
@Test
public void testLogicalTypesWithMultipleFields() throws Exception {
Schema logicalTypesWithMultipleFields = new Schema.Parser().parse(
new File("src/test/resources/logical_types_with_multiple_fields.avsc"));
assertCompilesWithJavaCompiler(
new SpecificCompiler(logicalTypesWithMultipleFields).compile());
}
@Test
public void testUnionAndFixedFields() throws Exception {
Schema unionTypesWithMultipleFields = new Schema.Parser().parse(
new File("src/test/resources/union_and_fixed_fields.avsc"));
assertCompilesWithJavaCompiler(
new SpecificCompiler(unionTypesWithMultipleFields).compile());
}
@Test
public void testConversionInstanceWithDecimalLogicalTypeDisabled() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(false);
Schema dateSchema = LogicalTypes.date()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeSchema = LogicalTypes.timeMillis()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeMicroSchema = LogicalTypes.timeMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampSchema = LogicalTypes.timestampMillis()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampMicrosSchema = LogicalTypes.timestampMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema decimalSchema = LogicalTypes.decimal(9,2)
.addToSchema(Schema.create(Schema.Type.BYTES));
Schema uuidSchema = LogicalTypes.uuid()
.addToSchema(Schema.create(Schema.Type.STRING));
Assert.assertEquals("Should use DATE_CONVERSION for date type",
"DATE_CONVERSION", compiler.conversionInstance(dateSchema));
Assert.assertEquals("Should use TIME_CONVERSION for time type",
"TIME_CONVERSION", compiler.conversionInstance(timeSchema));
Assert.assertEquals("Should use TIME_MICROS_CONVERSION for time type",
"TIME_MICROS_CONVERSION", compiler.conversionInstance(timeMicroSchema));
Assert.assertEquals("Should use TIMESTAMP_CONVERSION for date type",
"TIMESTAMP_CONVERSION", compiler.conversionInstance(timestampSchema));
Assert.assertEquals("Should use TIMESTAMP_MICROS_CONVERSION for date type",
"TIMESTAMP_MICROS_CONVERSION", compiler.conversionInstance(timestampMicrosSchema));
Assert.assertEquals("Should use null for decimal if the flag is off",
"null", compiler.conversionInstance(decimalSchema));
Assert.assertEquals("Should use null for decimal if the flag is off",
"null", compiler.conversionInstance(uuidSchema));
}
@Test
public void testConversionInstanceWithDecimalLogicalTypeEnabled() throws Exception {
SpecificCompiler compiler = createCompiler();
compiler.setEnableDecimalLogicalType(true);
Schema dateSchema = LogicalTypes.date()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeSchema = LogicalTypes.timeMillis()
.addToSchema(Schema.create(Schema.Type.INT));
Schema timeMicroSchema = LogicalTypes.timeMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampSchema = LogicalTypes.timestampMillis()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema timestampMicrosSchema = LogicalTypes.timestampMicros()
.addToSchema(Schema.create(Schema.Type.LONG));
Schema decimalSchema = LogicalTypes.decimal(9,2)
.addToSchema(Schema.create(Schema.Type.BYTES));
Schema uuidSchema = LogicalTypes.uuid()
.addToSchema(Schema.create(Schema.Type.STRING));
Assert.assertEquals("Should use DATE_CONVERSION for date type",
"DATE_CONVERSION", compiler.conversionInstance(dateSchema));
Assert.assertEquals("Should use TIME_CONVERSION for time type",
"TIME_CONVERSION", compiler.conversionInstance(timeSchema));
Assert.assertEquals("Should use TIME_MICROS_CONVERSION for time type",
"TIME_MICROS_CONVERSION", compiler.conversionInstance(timeMicroSchema));
Assert.assertEquals("Should use TIMESTAMP_CONVERSION for date type",
"TIMESTAMP_CONVERSION", compiler.conversionInstance(timestampSchema));
Assert.assertEquals("Should use TIMESTAMP_MICROS_CONVERSION for date type",
"TIMESTAMP_MICROS_CONVERSION", compiler.conversionInstance(timestampMicrosSchema));
Assert.assertEquals("Should use null for decimal if the flag is off",
"DECIMAL_CONVERSION", compiler.conversionInstance(decimalSchema));
Assert.assertEquals("Should use null for decimal if the flag is off",
"null", compiler.conversionInstance(uuidSchema));
}
public void testToFromByteBuffer() {
}
}