content: /*
   * Copyright 2017 The Apache Software Foundation.
   *
   * 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
   *
   *      https://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.specific;
  
  import java.io.ByteArrayInputStream;
  import java.io.ByteArrayOutputStream;
  import java.io.IOException;
  import java.nio.ByteBuffer;
  import java.util.HashMap;
  import java.util.Map;
  
  import org.apache.avro.Schema;
  import org.apache.avro.io.Encoder;
  import org.apache.avro.io.EncoderFactory;
  import org.apache.avro.io.Decoder;
  import org.apache.avro.io.DecoderFactory;
  import org.apache.avro.io.DatumReader;
  import org.apache.avro.io.DatumWriter;
  import org.apache.avro.specific.test.RecordWithErrorField;
  import org.apache.avro.specific.test.TestError;
  import org.apache.avro.util.Utf8;
  
  import org.junit.Assert;
  import org.junit.jupiter.api.BeforeEach;
  import org.junit.jupiter.api.Test;
  
  import org.apache.avro.specific.test.FullRecordV1;
  
  import static org.junit.jupiter.api.Assertions.assertTrue;
  import org.apache.avro.specific.test.FullRecordV2;
  
  public class TestGeneratedCode {
  
    private final static SpecificData MODEL = new SpecificData();
    private final static Schema V1S = FullRecordV1.getClassSchema();
    private final static Schema V2S = FullRecordV2.getClassSchema();
  
    @BeforeEach
    public void setUp() {
      MODEL.setCustomCoders(true);
    }
  
    @Test
    void withoutSchemaMigration() throws IOException {
      FullRecordV1 src = new FullRecordV1(true, 87231, 731L, 54.2832F, 38.321, "Hi there", null);
      assertTrue(((SpecificRecordBase) src).hasCustomCoders(), "Test schema must allow for custom coders.");
  
      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
      Encoder e = EncoderFactory.get().directBinaryEncoder(out, null);
      DatumWriter<FullRecordV1> w = (DatumWriter<FullRecordV1>) MODEL.createDatumWriter(V1S);
      w.write(src, e);
      e.flush();
  
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      Decoder d = DecoderFactory.get().directBinaryDecoder(in, null);
      DatumReader<FullRecordV1> r = (DatumReader<FullRecordV1>) MODEL.createDatumReader(V1S);
      FullRecordV1 dst = r.read(null, d);
  
      Assert.assertEquals(src, dst);
    }
  
    @Test
    void withSchemaMigration() throws IOException {
      Map<CharSequence, CharSequence> map = new HashMap<>();
      FullRecordV2 src = new FullRecordV2(true, 731, 87231, 38L, 54.2832F, "Hi there",
          ByteBuffer.wrap(Utf8.getBytesFor("Hello, world!")), map);
      assertTrue(((SpecificRecordBase) src).hasCustomCoders(), "Test schema must allow for custom coders.");
  
      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
      Encoder e = EncoderFactory.get().directBinaryEncoder(out, null);
      DatumWriter<FullRecordV2> w = (DatumWriter<FullRecordV2>) MODEL.createDatumWriter(V2S);
      w.write(src, e);
      e.flush();
  
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      Decoder d = DecoderFactory.get().directBinaryDecoder(in, null);
      DatumReader<FullRecordV1> r = (DatumReader<FullRecordV1>) MODEL.createDatumReader(V2S, V1S);
      FullRecordV1 dst = r.read(null, d);
  
      FullRecordV1 expected = new FullRecordV1(true, 87231, 731L, 54.2832F, 38.0, null, "Hello, world!");
      Assert.assertEquals(expected, dst);
    }
  
    @Test
    public void withErrorField() throws IOException {
      TestError srcError = TestError.newBuilder().setMessage$("Oops").build();
      RecordWithErrorField src = new RecordWithErrorField("Hi there", srcError);
      Assert.assertFalse("Test schema with error field cannot allow for custom coders.",
          ((SpecificRecordBase) src).hasCustomCoders());
      Schema schema = RecordWithErrorField.getClassSchema();
  
      ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
      Encoder e = EncoderFactory.get().directBinaryEncoder(out, null);
      DatumWriter<RecordWithErrorField> w = (DatumWriter<RecordWithErrorField>) MODEL.createDatumWriter(schema);
      w.write(src, e);
      e.flush();
  
      ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
      Decoder d = DecoderFactory.get().directBinaryDecoder(in, null);
      DatumReader<RecordWithErrorField> r = (DatumReader<RecordWithErrorField>) MODEL.createDatumReader(schema);
      RecordWithErrorField dst = r.read(null, d);
  
      TestError expectedError = TestError.newBuilder().setMessage$("Oops").build();
      RecordWithErrorField expected = new RecordWithErrorField("Hi there", expectedError);
      Assert.assertEquals(expected, dst);
    }
  }
  