content: package io.activej.serializer;
  
  import io.activej.serializer.annotations.Deserialize;
  import io.activej.serializer.annotations.Serialize;
  import io.activej.serializer.annotations.SerializeNullable;
  import io.activej.serializer.annotations.SerializeRecord;
  import io.activej.types.TypeT;
  import org.junit.Assert;
  import org.junit.Test;
  
  import java.util.List;
  
  import static io.activej.serializer.Utils.DEFINING_CLASS_LOADER;
  import static io.activej.serializer.Utils.doTest;
  import static java.util.Arrays.asList;
  
  public class RecordTest {
  
  	@SerializeRecord
  	public record Record(@SerializeNullable String s, int n) {}
  
  	@Test
  	public void testRecord() {
  		{
  			Record record1 = new Record("abc", 1);
  			Record record2 = doTest(Record.class, record1);
  			Assert.assertEquals(record1, record2);
  		}
  		{
  			Record record1 = new Record(null, 1);
  			Record record2 = doTest(Record.class, record1);
  			Assert.assertEquals(record1, record2);
  		}
  	}
  
  	@SuppressWarnings("ClassCanBeRecord")
  	public static final class CompatiblePojo {
  		private final String s;
  		private final int n;
  
  		public CompatiblePojo(@Deserialize("s") String s, @Deserialize("n") int n) {
  			this.s = s;
  			this.n = n;
  		}
  
  		@Serialize(order = 1)
  		@SerializeNullable
  		public String getS() {return s;}
  
  		@Serialize(order = 2)
  		public int getN() {return n;}
  	}
  
  	@Test
  	public void testCompatiblePojo() {
  		Record record = new Record("abc", 1);
  		BinarySerializer<Record> serializer = SerializerFactory.defaultInstance().create(DEFINING_CLASS_LOADER, Record.class);
  		BinarySerializer<CompatiblePojo> deserializer = SerializerFactory.defaultInstance().create(DEFINING_CLASS_LOADER, CompatiblePojo.class);
  		CompatiblePojo pojo = doTest(record, serializer, deserializer);
  		Assert.assertEquals(record.s, pojo.s);
  		Assert.assertEquals(record.n, pojo.n);
  	}
  
  	@SerializeRecord
  	public record GenericRecord<T>(@SerializeNullable T s, int n) {}
  
  	@Test
  	public void testGenericRecord() {
  		{
  			var record1 = new GenericRecord<String>("abc", 1);
  			BinarySerializer<GenericRecord<String>> serializer = SerializerFactory.defaultInstance().create(DEFINING_CLASS_LOADER, new TypeT<>() {});
  			var record2 = doTest(record1, serializer);
  			Assert.assertEquals(record1, record2);
  		}
  		{
  			var record1 = new GenericRecord<String>(null, 1);
  			var serializer = SerializerFactory.defaultInstance().create(DEFINING_CLASS_LOADER, new TypeT<GenericRecord<String>>() {});
  			var record2 = doTest(record1, serializer);
  			Assert.assertEquals(record1, record2);
  		}
  	}
  
  	@SerializeRecord
  	public record NestedRecord(@SerializeNullable Record record) {
  	}
  
  	@Test
  	public void testNestedRecords() {
  		{
  			Record record = new Record("abc", 1);
  			NestedRecord nestedRecord1 = new NestedRecord(record);
  			NestedRecord nestedRecord2 = doTest(NestedRecord.class, nestedRecord1);
  			Assert.assertEquals(nestedRecord1, nestedRecord2);
  		}
  		{
  			Record record = new Record(null, 1);
  			NestedRecord nestedRecord1 = new NestedRecord(record);
  			NestedRecord nestedRecord2 = doTest(NestedRecord.class, nestedRecord1);
  			Assert.assertEquals(nestedRecord1, nestedRecord2);
  		}
  		{
  			NestedRecord nestedRecord1 = new NestedRecord(null);
  			NestedRecord nestedRecord2 = doTest(NestedRecord.class, nestedRecord1);
  			Assert.assertEquals(nestedRecord1, nestedRecord2);
  		}
  	}
  
  	@SerializeRecord
  	public record RecordWithNestedNullables(@SerializeNullable List<@SerializeNullable String> list, int n) {}
  
  	@Test
  	public void testRecordsNestedNullable() {
  		{
  			RecordWithNestedNullables record1 = new RecordWithNestedNullables(List.of("abc", "xyz"), 1);
  			RecordWithNestedNullables record2 = doTest(RecordWithNestedNullables.class, record1);
  			Assert.assertEquals(record1, record2);
  		}
  		{
  			RecordWithNestedNullables record1 = new RecordWithNestedNullables(asList("abc", null), 1);
  			RecordWithNestedNullables record2 = doTest(RecordWithNestedNullables.class, record1);
  			Assert.assertEquals(record1, record2);
  		}
  		{
  			RecordWithNestedNullables record1 = new RecordWithNestedNullables(null, 1);
  			RecordWithNestedNullables record2 = doTest(RecordWithNestedNullables.class, record1);
  			Assert.assertEquals(record1, record2);
  		}
  	}
  
  }
  