Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions grpc/grpc-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import kotlinx.rpc.proto.kotlinMultiplatform
import org.gradle.internal.extensions.stdlib.capitalized
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinNativeTarget
import org.jetbrains.kotlin.gradle.tasks.CInteropProcess
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
alias(libs.plugins.conventions.kmp)
Expand Down Expand Up @@ -159,5 +160,12 @@ rpc {
dependsOn(gradle.includedBuild("protoc-gen").task(":jar"))
}
}

// generate protos before compiling tests
project.tasks.withType<KotlinCompile>().configureEach {
if (name.startsWith("compileTest")) {
dependsOn(project.tasks.withType<BufGenerateTask>())
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,20 @@

package kotlinx.rpc.grpc.pb

import OneOfMsg
import OneOfMsgInternal
import invoke
import kotlinx.io.Buffer
import kotlinx.rpc.grpc.internal.MessageCodec
import kotlinx.rpc.grpc.test.Enum
import kotlinx.rpc.grpc.test.UsingEnum
import kotlinx.rpc.grpc.test.UsingEnumInternal
import kotlinx.rpc.grpc.test.common.*
import kotlinx.rpc.grpc.test.invoke
import kotlin.test.Test
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNull

class ProtosTest {

Expand Down Expand Up @@ -84,5 +92,78 @@ class ProtosTest {
}
}

@Test
fun testEnumUnrecognized() {
// write unknown enum value
val buffer = Buffer()
val encoder = WireEncoder(buffer)
encoder.writeEnum(1, 50)
encoder.flush()

val decodedMsg = UsingEnumInternal.CODEC.decode(buffer)
assertEquals(Enum.UNRECOGNIZED(50), decodedMsg.enum)
}

@Test
fun testEnumAlias() {
val msg = UsingEnum {
enum = Enum.ONE_SECOND
}

val decodedMsg = decodeEncode(msg, UsingEnumInternal.CODEC)
assertEquals(Enum.ONE, decodedMsg.enum)
assertEquals(Enum.ONE_SECOND, decodedMsg.enum)
}

@Test
fun testDefault() {
// create message without enum field set
val msg = UsingEnum {}

val buffer = UsingEnumInternal.CODEC.encode(msg) as Buffer
// buffer should be empty (default is not in wire)
assertEquals(0, buffer.size)

val decoded = UsingEnumInternal.CODEC.decode(buffer)
assertEquals(Enum.ZERO, decoded.enum)
}

@Test
fun testOneOf() {
val msg1 = OneOfMsg {
field = OneOfMsg.Field.Sint(23)
}
val decoded1 = decodeEncode(msg1, OneOfMsgInternal.CODEC)
assertEquals(OneOfMsg.Field.Sint(23), decoded1.field)

val msg2 = OneOfMsg {
field = OneOfMsg.Field.Fixed(21u)
}
val decoded2 = decodeEncode(msg2, OneOfMsgInternal.CODEC)
assertEquals(OneOfMsg.Field.Fixed(21u), decoded2.field)
}

@Test
fun testOneOfLastWins() {
// write two values on the oneOf field.
// the second value must be the one stored during decoding.
val buffer = Buffer()
val encoder = WireEncoder(buffer)
encoder.writeInt32(2, 99)
encoder.writeFixed64(3, 123u)
encoder.flush()

val decoded = OneOfMsgInternal.CODEC.decode(buffer)
assertEquals(OneOfMsg.Field.Fixed(123u), decoded.field)
}

@Test
fun testOneOfNull() {
// write two values on the oneOf field.
// the second value must be the one stored during decoding.
val buffer = Buffer()
val decoded = OneOfMsgInternal.CODEC.decode(buffer)
assertNull(decoded.field)
}

}
6 changes: 6 additions & 0 deletions grpc/grpc-core/src/commonTest/proto/oneof.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
message OneOfMsg {
oneof field {
int32 sint = 2;
fixed64 fixed = 3;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,12 @@ open class CodeGenerator(

internal fun whenBlock(
condition: String? = null,
prefix: String = "",
block: (CodeGenerator.() -> Unit),
) {
val pre = if (prefix.isNotEmpty()) prefix.trim() + " " else ""
val cond = condition?.let { " ($it)" } ?: ""
scope("when$cond", block = block)
scope("${pre}when$cond", block = block)
}

internal fun whenCase(
Expand Down
Loading
Loading