1 /* 2 * Copyright 2017-2023 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license. 3 */ 4 5 package kotlinx.serialization.protobuf.conformance 6 7 import com.google.protobuf_test_messages.proto3.* 8 import io.kotlintest.properties.* 9 import kotlinx.serialization.* 10 import kotlinx.serialization.protobuf.* 11 import kotlin.test.* 12 13 @Serializable 14 data class KTestMessagesProto3Repeated( 15 @ProtoNumber(31) @ProtoPacked val repeatedInt32: List<Int> = emptyList(), 16 @ProtoNumber(32) @ProtoPacked val repeatedInt64: List<Long> = emptyList(), 17 @ProtoNumber(33) @ProtoPacked val repeatedUint32: List<UInt> = emptyList(), 18 @ProtoNumber(34) @ProtoPacked val repeatedUint64: List<ULong> = emptyList(), 19 @ProtoNumber(35) @ProtoPacked val repeatedSint32: List<Int> = emptyList(), 20 @ProtoNumber(36) @ProtoPacked val repeatedSint64: List<Long> = emptyList(), 21 @ProtoNumber(37) @ProtoPacked val repeatedFixed32: List<Int> = emptyList(), 22 @ProtoNumber(38) @ProtoPacked val repeatedFixed64: List<Long> = emptyList(), 23 @ProtoNumber(39) @ProtoPacked val repeatedSfixed32: List<Int> = emptyList(), 24 @ProtoNumber(40) @ProtoPacked val repeatedSfixed64: List<Long> = emptyList(), 25 @ProtoNumber(41) @ProtoPacked val repeatedFloat: List<Float> = emptyList(), 26 @ProtoNumber(42) @ProtoPacked val repeatedDouble: List<Double> = emptyList(), 27 @ProtoNumber(43) @ProtoPacked val repeatedBool: List<Boolean> = emptyList(), 28 @ProtoNumber(44) val repeatedString: List<String> = emptyList(), 29 @ProtoNumber(45) val repeatedBytes: List<ByteArray> = emptyList(), 30 @ProtoNumber(48) val repeatedNestedMessages: List<KTestMessagesProto3Message.KNestedMessage> = emptyList(), 31 @ProtoNumber(49) val repeatedForeignMessages: List<KForeignMessage> = emptyList(), 32 ) 33 34 class Proto3RepeatedTest { 35 @Test defaultnull36 fun default() { 37 val message = KTestMessagesProto3Repeated( 38 repeatedInt32 = Gen.list(Gen.int()).generate(), 39 repeatedInt64 = Gen.list(Gen.long()).generate(), 40 repeatedFloat = Gen.list(Gen.float()).generate(), 41 repeatedDouble = Gen.list(Gen.double()).generate(), 42 repeatedBool = Gen.list(Gen.bool()).generate(), 43 repeatedString = Gen.list(Gen.string()).generate(), 44 repeatedBytes = Gen.list(Gen.string().map { it.toByteArray() }).generate(), 45 repeatedNestedMessages = listOf( 46 KTestMessagesProto3Message.KNestedMessage( 47 1, 48 null 49 ), 50 KTestMessagesProto3Message.KNestedMessage( 51 2, 52 KTestMessagesProto3Message( 53 KTestMessagesProto3Message.KNestedMessage(3, null), 54 ) 55 ) 56 ), 57 repeatedForeignMessages = listOf( 58 KForeignMessage(1), 59 KForeignMessage(-12), 60 ) 61 ) 62 63 val bytes = ProtoBuf.encodeToByteArray(message) 64 val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes) 65 66 assertEquals(message.repeatedInt32, restored.repeatedInt32List) 67 assertEquals(message.repeatedInt64, restored.repeatedInt64List) 68 assertEquals(message.repeatedFloat, restored.repeatedFloatList) 69 assertEquals(message.repeatedDouble, restored.repeatedDoubleList) 70 assertEquals(message.repeatedBool, restored.repeatedBoolList) 71 assertEquals(message.repeatedString, restored.repeatedStringList) 72 assertEquals(message.repeatedNestedMessages.map { it.toProto() }, restored.repeatedNestedMessageList) 73 assertEquals(message.repeatedForeignMessages.map { it.toProto() }, restored.repeatedForeignMessageList) 74 assertEquals(message.repeatedBytes.map { it.toList() }, restored.repeatedBytesList.map { it.toList() }) 75 76 val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray()) 77 // [equals] method is not implemented for [ByteArray] so we need to compare it separately. 78 assertEquals(message, restoredMessage.copy(repeatedBytes = message.repeatedBytes)) 79 assertContentEquals( 80 message.repeatedBytes.flatMap { it.toList() }, 81 restoredMessage.repeatedBytes.flatMap { it.toList() }, 82 ) 83 } 84 85 @Test 86 @Ignore 87 // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2419 signedAndFixednull88 fun signedAndFixed() { 89 val message = KTestMessagesProto3Repeated( 90 repeatedSint32 = Gen.list(Gen.int()).generate(), 91 repeatedSint64 = Gen.list(Gen.long()).generate(), 92 repeatedFixed32 = Gen.list(Gen.int()).generate(), 93 repeatedFixed64 = Gen.list(Gen.long()).generate(), 94 repeatedSfixed32 = Gen.list(Gen.int()).generate(), 95 repeatedSfixed64 = Gen.list(Gen.long()).generate(), 96 ) 97 98 val bytes = ProtoBuf.encodeToByteArray(message) 99 val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes) 100 101 assertEquals(message.repeatedUint32, restored.repeatedUint32List.map { it.toUInt() }) 102 assertEquals(message.repeatedUint64, restored.repeatedUint64List.map { it.toULong() }) 103 assertEquals(message.repeatedSint32, restored.repeatedSint32List) 104 assertEquals(message.repeatedSint64, restored.repeatedSint64List) 105 assertEquals(message.repeatedFixed32, restored.repeatedFixed32List) 106 assertEquals(message.repeatedFixed64, restored.repeatedFixed64List) 107 assertEquals(message.repeatedSfixed32, restored.repeatedSfixed32List) 108 assertEquals(message.repeatedSfixed64, restored.repeatedSfixed64List) 109 110 val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray()) 111 assertEquals(message, restoredMessage) 112 } 113 114 115 @Test 116 @Ignore 117 // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2418 unsignednull118 fun unsigned() { 119 val message = KTestMessagesProto3Repeated( 120 repeatedUint32 = Gen.list(Gen.int().map { it.toUInt() }).generate(), 121 repeatedUint64 = Gen.list(Gen.long().map { it.toULong() }).generate(), 122 ) 123 124 val bytes = ProtoBuf.encodeToByteArray(message) 125 val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes) 126 127 assertEquals(message.repeatedUint32, restored.repeatedUint32List.map { it.toUInt() }) 128 assertEquals(message.repeatedUint64, restored.repeatedUint64List.map { it.toULong() }) 129 130 val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Repeated>(restored.toByteArray()) 131 assertEquals(message, restoredMessage) 132 } 133 } 134