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 KTestMessagesProto3Map( 15 @ProtoNumber(56) val mapInt32Int32: Map<Int, Int> = emptyMap(), 16 @ProtoNumber(57) val mapInt64Int64: Map<Long, Long> = emptyMap(), 17 @ProtoNumber(58) val mapUint32Uint32: Map<UInt, UInt> = emptyMap(), 18 @ProtoNumber(59) val mapUint64Uint64: Map<ULong, ULong> = emptyMap(), 19 @ProtoNumber(60) val mapSint32Sint32: Map<Int, Int> = emptyMap(), 20 @ProtoNumber(61) val mapSint64Sint64: Map<Long, Long> = emptyMap(), 21 @ProtoNumber(62) val mapFixed32Fixed32: Map<Int, Int> = emptyMap(), 22 @ProtoNumber(63) val mapFixed64Fixed64: Map<Long, Long> = emptyMap(), 23 @ProtoNumber(64) val mapSfixed32Sfixed32: Map<Int, Int> = emptyMap(), 24 @ProtoNumber(65) val mapSfixed64Sfixed64: Map<Long, Long> = emptyMap(), 25 @ProtoNumber(66) val mapInt32Float: Map<Int, Float> = emptyMap(), 26 @ProtoNumber(67) val mapInt32Double: Map<Int, Double> = emptyMap(), 27 @ProtoNumber(68) val mapBoolBool: Map<Boolean, Boolean> = emptyMap(), 28 @ProtoNumber(69) val mapStringString: Map<String, String> = emptyMap(), 29 @ProtoNumber(70) val mapStringBytes: Map<String, ByteArray> = emptyMap(), 30 @ProtoNumber(71) val mapStringNestedMessage: Map<String, KTestMessagesProto3Message.KNestedMessage> = emptyMap(), 31 @ProtoNumber(72) val mapStringForeignMessage: Map<String, KForeignMessage> = emptyMap(), 32 @ProtoNumber(73) val mapStringNestedEnum: Map<String, KTestMessagesProto3Enum.KNestedEnum> = emptyMap(), 33 @ProtoNumber(74) val mapStringForeignEnum: Map<String, KForeignEnum> = emptyMap(), 34 ) 35 36 class Proto3MapTest { 37 @Test defaultnull38 fun default() { 39 val message = KTestMessagesProto3Map( 40 mapInt32Int32 = Gen.map(Gen.int(), Gen.int()).generate(), 41 mapInt64Int64 = Gen.map(Gen.long(), Gen.long()).generate(), 42 mapUint32Uint32 = Gen.map(Gen.int().map { it.toUInt() }, Gen.int().map { it.toUInt() }).generate(), 43 mapUint64Uint64 = Gen.map(Gen.int().map { it.toULong() }, Gen.int().map { it.toULong() }).generate(), 44 mapInt32Float = Gen.map(Gen.int(), Gen.float()).generate(), 45 mapInt32Double = Gen.map(Gen.int(), Gen.double()).generate(), 46 mapBoolBool = Gen.map(Gen.bool(), Gen.bool()).generate(), 47 mapStringString = Gen.map(Gen.string(), Gen.string()).generate(), 48 mapStringBytes = Gen.map(Gen.string(), Gen.string().map { it.toByteArray() }).generate(), 49 mapStringNestedMessage = mapOf( 50 "asd_1" to KTestMessagesProto3Message.KNestedMessage( 51 1, 52 null 53 ), 54 "asi_#" to KTestMessagesProto3Message.KNestedMessage( 55 2, 56 KTestMessagesProto3Message( 57 KTestMessagesProto3Message.KNestedMessage(3, null), 58 ) 59 ) 60 ), 61 mapStringForeignMessage = mapOf( 62 "" to KForeignMessage(1), 63 "-2" to KForeignMessage(-12), 64 ), 65 mapStringNestedEnum = Gen.map( 66 Gen.string(), Gen.oneOf( 67 KTestMessagesProto3Enum.KNestedEnum.entries, 68 ) 69 ).generate(), 70 mapStringForeignEnum = Gen.map( 71 Gen.string(), Gen.oneOf( 72 KForeignEnum.entries, 73 ) 74 ).generate(), 75 ) 76 77 val bytes = ProtoBuf.encodeToByteArray(message) 78 val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes) 79 80 81 assertEquals(message.mapInt32Int32, restored.mapInt32Int32Map) 82 assertEquals(message.mapInt64Int64, restored.mapInt64Int64Map) 83 assertEquals( 84 message.mapUint32Uint32, 85 restored.mapUint32Uint32Map.map { it.key.toUInt() to it.value.toUInt() }.toMap() 86 ) 87 assertEquals( 88 message.mapUint64Uint64, 89 restored.mapUint64Uint64Map.map { it.key.toULong() to it.value.toULong() }.toMap() 90 ) 91 assertEquals(message.mapInt32Float, restored.mapInt32FloatMap) 92 assertEquals(message.mapInt32Double, restored.mapInt32DoubleMap) 93 assertEquals(message.mapBoolBool, restored.mapBoolBoolMap) 94 assertEquals(message.mapStringString, restored.mapStringStringMap) 95 assertContentEquals( 96 message.mapStringBytes.mapValues { it.value.toString(Charsets.UTF_32) }.entries.toList(), 97 restored.mapStringBytesMap.mapValues { it.value.toByteArray().toString(Charsets.UTF_32) }.entries.toList() 98 ) 99 assertEquals( 100 message.mapStringNestedMessage.mapValues { it.value.toProto() }, 101 restored.mapStringNestedMessageMap 102 ) 103 assertEquals( 104 message.mapStringForeignMessage.mapValues { it.value.toProto() }, 105 restored.mapStringForeignMessageMap 106 ) 107 assertEquals( 108 message.mapStringNestedEnum.mapValues { it.value.name }, 109 restored.mapStringNestedEnumMap.mapValues { it.value.name }, 110 ) 111 assertEquals( 112 message.mapStringForeignEnum.mapValues { it.value.name }, 113 restored.mapStringForeignEnumMap.mapValues { it.value.name } 114 ) 115 116 val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Map>(restored.toByteArray()) 117 assertEquals(message.copy(mapStringBytes = mapOf()), restoredMessage.copy(mapStringBytes = mapOf())) 118 } 119 120 @Test 121 @Ignore 122 // Issue: https://github.com/Kotlin/kotlinx.serialization/issues/2417 signedAndFixednull123 fun signedAndFixed() { 124 val message = KTestMessagesProto3Map( 125 mapSint32Sint32 = Gen.map(Gen.int(), Gen.int()).generate(), 126 mapSint64Sint64 = Gen.map(Gen.long(), Gen.long()).generate(), 127 mapFixed32Fixed32 = Gen.map(Gen.int(), Gen.int()).generate(), 128 mapFixed64Fixed64 = Gen.map(Gen.long(), Gen.long()).generate(), 129 mapSfixed32Sfixed32 = Gen.map(Gen.int(), Gen.int()).generate(), 130 mapSfixed64Sfixed64 = Gen.map(Gen.long(), Gen.long()).generate(), 131 ) 132 133 val bytes = ProtoBuf.encodeToByteArray(message) 134 val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes) 135 136 137 assertContentEquals(message.mapSint32Sint32.entries.toList(), restored.mapSint32Sint32Map.entries.toList()) 138 assertContentEquals(message.mapSint64Sint64.entries.toList(), restored.mapSint64Sint64Map.entries.toList()) 139 assertContentEquals(message.mapFixed32Fixed32.entries.toList(), restored.mapFixed32Fixed32Map.entries.toList()) 140 assertContentEquals(message.mapFixed64Fixed64.entries.toList(), restored.mapFixed64Fixed64Map.entries.toList()) 141 assertContentEquals( 142 message.mapSfixed32Sfixed32.entries.toList(), 143 restored.mapSfixed32Sfixed32Map.entries.toList() 144 ) 145 assertContentEquals( 146 message.mapSfixed64Sfixed64.entries.toList(), 147 restored.mapSfixed64Sfixed64Map.entries.toList() 148 ) 149 150 151 val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessagesProto3Map>(restored.toByteArray()) 152 assertEquals(message, restoredMessage) 153 } 154 } 155