1 /*
<lambda>null2  * 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 kotlinx.serialization.*
9 import kotlinx.serialization.protobuf.*
10 import kotlin.test.*
11 
12 @Serializable
13 data class KTestMessageProto3Oneof(
14     @ProtoNumber(111) val oneofUint32: UInt? = null,
15     @ProtoNumber(112) val oneofNestedMessage: KTestMessagesProto3Message.KNestedMessage? = null,
16     @ProtoNumber(113) val oneofString: String? = null,
17     @ProtoNumber(114) val oneofBytes: ByteArray? = null,
18     @ProtoNumber(115) val oneofBool: Boolean? = null,
19     @ProtoNumber(116) val oneofUint64: ULong? = null,
20     @ProtoNumber(117) val oneofFloat: Float? = null,
21     @ProtoNumber(118) val oneofDouble: Double? = null,
22     @ProtoNumber(119) val oneofEnum: KTestMessagesProto3Enum.KNestedEnum? = null,
23 ) {
24     init {
25         require(
26             listOf(
27                 oneofUint32,
28                 oneofNestedMessage,
29                 oneofString,
30                 oneofBytes,
31                 oneofBool,
32                 oneofUint64,
33                 oneofFloat,
34                 oneofDouble,
35                 oneofEnum,
36             ).count { it != null } == 1
37         )
38     }
39 }
40 
41 class Proto3OneofTest {
42 
43     /**
44      * Verify that the given [KTestMessageProto3Oneof] is correctly encoded and decoded as
45      * [TestMessagesProto3.TestAllTypesProto3] by running the [verificationFunction]. This
46      * method also verifies that the encoded and decoded message is equal to the original message.
47      *
48      * @param verificationFunction a function that verifies the encoded and decoded message. First parameter
49      * is the original message and the second parameter is the decoded protobuf library message.
50      * @receiver the [KTestMessageProto3Oneof] to verify
51      */
verifynull52     private fun KTestMessageProto3Oneof.verify(
53         verificationFunction: (KTestMessageProto3Oneof, TestMessagesProto3.TestAllTypesProto3) -> Unit,
54     ) {
55         val bytes = ProtoBuf.encodeToByteArray(this)
56         val restored = TestMessagesProto3.TestAllTypesProto3.parseFrom(bytes)
57 
58         verificationFunction.invoke(this, restored)
59 
60         val restoredMessage = ProtoBuf.decodeFromByteArray<KTestMessageProto3Oneof>(restored.toByteArray())
61 
62         // [equals] method is not implemented for [ByteArray] so we need to compare it separately.
63         assertEquals(this, restoredMessage.copy(oneofBytes = this.oneofBytes))
64         assertContentEquals(this.oneofBytes, restoredMessage.oneofBytes)
65     }
66 
67     @Test
uint32null68     fun uint32() {
69         KTestMessageProto3Oneof(oneofUint32 = 150u).verify { self, restored ->
70             assertEquals(self.oneofUint32, restored.oneofUint32.toUInt())
71         }
72     }
73 
74     @Test
nestedMessagenull75     fun nestedMessage() {
76         KTestMessageProto3Oneof(
77             oneofNestedMessage = KTestMessagesProto3Message.KNestedMessage(a = 150),
78         ).verify { self, restored ->
79             assertEquals(self.oneofNestedMessage?.a, restored.oneofNestedMessage.a)
80         }
81     }
82 
83     @Test
stringnull84     fun string() {
85         KTestMessageProto3Oneof(oneofString = "150").verify { self, restored ->
86             assertEquals(self.oneofString, restored.oneofString)
87         }
88     }
89 
90     @Test
bytesnull91     fun bytes() {
92         KTestMessageProto3Oneof(oneofBytes = "150".toByteArray()).verify { self, restored ->
93             assertContentEquals(self.oneofBytes, restored.oneofBytes.toByteArray())
94         }
95     }
96 
97     @Test
boolnull98     fun bool() {
99         KTestMessageProto3Oneof(oneofBool = true).verify { self, restored ->
100             assertEquals(self.oneofBool, restored.oneofBool)
101         }
102     }
103 
104     @Test
uint64null105     fun uint64() {
106         KTestMessageProto3Oneof(oneofUint64 = 150uL).verify { self, restored ->
107             assertEquals(self.oneofUint64, restored.oneofUint64.toULong())
108         }
109     }
110 
111     @Test
floatnull112     fun float() {
113         KTestMessageProto3Oneof(oneofFloat = 150f).verify { self, restored ->
114             assertEquals(self.oneofFloat, restored.oneofFloat)
115         }
116     }
117 
118     @Test
doublenull119     fun double() {
120         KTestMessageProto3Oneof(oneofDouble = 150.0).verify { self, restored ->
121             assertEquals(self.oneofDouble, restored.oneofDouble)
122         }
123     }
124 
125     @Test
enumnull126     fun enum() {
127         KTestMessageProto3Oneof(oneofEnum = KTestMessagesProto3Enum.KNestedEnum.BAR).verify { self, restored ->
128             assertEquals(self.oneofEnum?.name, restored.oneofEnum.name)
129         }
130     }
131 }
132