From 9348a8db1b2710edd0b0d2be11d9708498378e82 Mon Sep 17 00:00:00 2001 From: Chuckame Date: Wed, 25 Sep 2024 23:55:20 +0200 Subject: [PATCH] Improve enum test coverage --- .editorconfig | 4 ++ .../avrokotlin/avro4k/AvroAssertions.kt | 61 ++++++++++++++++++- .../avro4k/encoding/EnumEncodingTest.kt | 23 ++++++- 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/.editorconfig b/.editorconfig index d24e3874..281f3d13 100644 --- a/.editorconfig +++ b/.editorconfig @@ -23,6 +23,10 @@ ij_editorconfig_spaces_around_assignment_operators = true [{*.kt,*.kts}] ktlint_standard_filename = disabled +ktlint_standard_class-signature = disabled +ktlint_standard_function-signature = disabled +ktlint_standard_chain-method-continuation = disabled +ktlint_standard_function-expression-body = disabled ij_kotlin_align_in_columns_case_branch = false ij_kotlin_align_multiline_binary_operation = false ij_kotlin_align_multiline_extends_list = false diff --git a/src/test/kotlin/com/github/avrokotlin/avro4k/AvroAssertions.kt b/src/test/kotlin/com/github/avrokotlin/avro4k/AvroAssertions.kt index 0648ac3a..86637da8 100644 --- a/src/test/kotlin/com/github/avrokotlin/avro4k/AvroAssertions.kt +++ b/src/test/kotlin/com/github/avrokotlin/avro4k/AvroAssertions.kt @@ -221,49 +221,106 @@ fun encodeToBytesUsingApacheLib( internal inline fun StringSpecRootScope.basicScalarEncodeDecodeTests(value: T, schema: Schema, apacheCompatibleValue: Any? = value) { "support scalar type ${schema.type} serialization" { + Avro.schema() shouldBe schema testEncodeDecode(schema, value, apacheCompatibleValue = apacheCompatibleValue) + Avro.schema>() shouldBe schema testEncodeDecode(schema, TestGenericValueClass(value), apacheCompatibleValue = apacheCompatibleValue) + Avro.schema() shouldBe schema.nullable testEncodeDecode(schema.nullable, value, apacheCompatibleValue = apacheCompatibleValue) testEncodeDecode(schema.nullable, null) + Avro.schema>() shouldBe schema.nullable testEncodeDecode(schema.nullable, TestGenericValueClass(value), apacheCompatibleValue = apacheCompatibleValue) testEncodeDecode(schema.nullable, TestGenericValueClass(null), apacheCompatibleValue = null) + Avro.schema?>() shouldBe schema.nullable testEncodeDecode?>(schema.nullable, null) + Avro.schema?>() shouldBe schema.nullable + testEncodeDecode?>(schema.nullable, null) } "scalar type ${schema.type} in record" { val record = SchemaBuilder.record("theRecord").fields() .name("field").type(schema).noDefault() .endRecord() - + Avro.schema>() shouldBe record + Avro.schema>>() shouldBe record testEncodeDecode(record, TestGenericRecord(value), apacheCompatibleValue = GenericData.Record(record).also { it.put(0, apacheCompatibleValue) }) testEncodeDecode(record, TestGenericRecord(TestGenericValueClass(value)), apacheCompatibleValue = GenericData.Record(record).also { it.put(0, apacheCompatibleValue) }) + val expectedRecordSchemaNullable = + SchemaBuilder.record("theRecord").fields() + .name("field").type(schema.nullable).withDefault(null) + .endRecord() + Avro.schema>() shouldBe expectedRecordSchemaNullable + Avro.schema>>() shouldBe expectedRecordSchemaNullable + Avro.schema?>>() shouldBe expectedRecordSchemaNullable + Avro.schema?>>() shouldBe expectedRecordSchemaNullable + val recordNullable = SchemaBuilder.record("theRecord").fields() .name("field").type(schema.nullable).noDefault() .endRecord() testEncodeDecode(recordNullable, TestGenericRecord(value), apacheCompatibleValue = GenericData.Record(recordNullable).also { it.put(0, apacheCompatibleValue) }) testEncodeDecode(recordNullable, TestGenericRecord(null), apacheCompatibleValue = GenericData.Record(recordNullable).also { it.put(0, null) }) - testEncodeDecode(recordNullable, TestGenericRecord(TestGenericValueClass(value)), apacheCompatibleValue = GenericData.Record(recordNullable).also { it.put(0, apacheCompatibleValue) }) + testEncodeDecode( + recordNullable, + TestGenericRecord(TestGenericValueClass(value)), + apacheCompatibleValue = GenericData.Record(recordNullable).also { it.put(0, apacheCompatibleValue) } + ) testEncodeDecode(recordNullable, TestGenericRecord(TestGenericValueClass(null)), apacheCompatibleValue = GenericData.Record(recordNullable).also { it.put(0, null) }) } "scalar type ${schema.type} in map" { val map = SchemaBuilder.map().values(schema) + Avro.schema>() shouldBe map + Avro.schema>>() shouldBe map + Avro.schema>>() shouldBe map + Avro.schema, TestGenericValueClass>>() shouldBe map + Avro.schema>() shouldBe map + Avro.schema, T>>() shouldBe map testEncodeDecode(map, mapOf("key" to value), apacheCompatibleValue = mapOf("key" to apacheCompatibleValue)) testEncodeDecode(map, mapOf("key" to TestGenericValueClass(value)), apacheCompatibleValue = mapOf("key" to apacheCompatibleValue)) val mapNullable = SchemaBuilder.map().values(schema.nullable) + Avro.schema>() shouldBe mapNullable + Avro.schema>>() shouldBe mapNullable + Avro.schema?>>() shouldBe mapNullable + Avro.schema?>>() shouldBe mapNullable + Avro.schema>>() shouldBe mapNullable + Avro.schema?>>() shouldBe mapNullable + Avro.schema?>>() shouldBe mapNullable + Avro.schema, TestGenericValueClass>>() shouldBe mapNullable + Avro.schema, TestGenericValueClass?>>() shouldBe mapNullable + Avro.schema, TestGenericValueClass?>>() shouldBe mapNullable + Avro.schema>() shouldBe mapNullable + Avro.schema, T?>>() shouldBe mapNullable testEncodeDecode(mapNullable, mapOf("key" to TestGenericValueClass(value)), apacheCompatibleValue = mapOf("key" to apacheCompatibleValue)) testEncodeDecode(mapNullable, mapOf("key" to TestGenericValueClass(null)), apacheCompatibleValue = mapOf("key" to null)) } "scalar type ${schema.type} in array" { val array = SchemaBuilder.array().items(schema) + Avro.schema>() shouldBe array + Avro.schema>>() shouldBe array + Avro.schema>() shouldBe array + Avro.schema>>() shouldBe array + Avro.schema>() shouldBe array + Avro.schema>>() shouldBe array testEncodeDecode(array, listOf(value), apacheCompatibleValue = listOf(apacheCompatibleValue)) testEncodeDecode(array, listOf(TestGenericValueClass(value)), apacheCompatibleValue = listOf(apacheCompatibleValue)) val arrayNullable = SchemaBuilder.array().items(schema.nullable) + Avro.schema>() shouldBe arrayNullable + Avro.schema>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable + Avro.schema?>>() shouldBe arrayNullable testEncodeDecode(arrayNullable, listOf(TestGenericValueClass(value)), apacheCompatibleValue = listOf(apacheCompatibleValue)) testEncodeDecode(arrayNullable, listOf(TestGenericValueClass(null)), apacheCompatibleValue = listOf(null)) } diff --git a/src/test/kotlin/com/github/avrokotlin/avro4k/encoding/EnumEncodingTest.kt b/src/test/kotlin/com/github/avrokotlin/avro4k/encoding/EnumEncodingTest.kt index 4858dff9..9d928d0f 100644 --- a/src/test/kotlin/com/github/avrokotlin/avro4k/encoding/EnumEncodingTest.kt +++ b/src/test/kotlin/com/github/avrokotlin/avro4k/encoding/EnumEncodingTest.kt @@ -13,6 +13,7 @@ import com.github.avrokotlin.avro4k.schema import com.github.avrokotlin.avro4k.serializer.UUIDSerializer import io.kotest.assertions.throwables.shouldThrow import io.kotest.core.spec.style.StringSpec +import io.kotest.matchers.shouldBe import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException @@ -21,10 +22,21 @@ import org.apache.avro.SchemaBuilder import org.apache.avro.generic.GenericData internal class EnumEncodingTest : StringSpec({ + val expectedEnumSchema = SchemaBuilder.enumeration(Cream::class.qualifiedName).symbols("Bruce", "Baker", "Clapton") + basicScalarEncodeDecodeTests(Cream.Bruce, expectedEnumSchema, apacheCompatibleValue = GenericData.EnumSymbol(expectedEnumSchema, "Bruce")) - basicScalarEncodeDecodeTests(Cream.Bruce, Avro.schema(), apacheCompatibleValue = GenericData.EnumSymbol(Avro.schema(), "Bruce")) + "Only allow 1 @AvroEnumDefault at max" { + shouldThrow { + Avro.schema() + } + } "Decoding enum with an unknown symbol uses @AvroEnumDefault value" { + Avro.schema() shouldBe + SchemaBuilder.enumeration("Enum") + .defaultSymbol("UNKNOWN") + .symbols("UNKNOWN", "A", "B") + AvroAssertions.assertThat(EnumV2WrapperRecord(EnumV2.B)) .isEncodedAs(record(GenericData.EnumSymbol(Avro.schema(), "B"))) .isDecodedAs(EnumV1WrapperRecord(EnumV1.UNKNOWN)) @@ -71,6 +83,15 @@ internal class EnumEncodingTest : StringSpec({ A, } + @Serializable + private enum class BadEnumWithManyDefaults { + @AvroEnumDefault + DEF1, + + @AvroEnumDefault + DEF2, + } + @Serializable @SerialName("Enum") private enum class EnumV1WithoutDefault {