From bc726eada9ede8a396f0df390c1a46db58cdbab7 Mon Sep 17 00:00:00 2001 From: sergeych Date: Mon, 19 Dec 2022 04:33:36 +0100 Subject: [PATCH] added opt tool --- build.gradle.kts | 2 +- .../kotlin/net.sergeych.tools/Opt.kt | 25 ++++++++++ .../net/sergeych/parsec3/WsServerKtTest.kt | 48 +++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 src/commonMain/kotlin/net.sergeych.tools/Opt.kt diff --git a/build.gradle.kts b/build.gradle.kts index a7fafd1..5af23b0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,7 +10,7 @@ plugins { } group = "net.sergeych" -version = "0.4.0-SNAPSHOT" +version = "0.4.1-SNAPSHOT" repositories { mavenCentral() diff --git a/src/commonMain/kotlin/net.sergeych.tools/Opt.kt b/src/commonMain/kotlin/net.sergeych.tools/Opt.kt new file mode 100644 index 0000000..4aab959 --- /dev/null +++ b/src/commonMain/kotlin/net.sergeych.tools/Opt.kt @@ -0,0 +1,25 @@ +package net.sergeych.tools + +import kotlinx.serialization.Serializable + +@Serializable +class Opt(val value: T?) { + override fun hashCode(): Int { + return value.hashCode() + } + + override fun equals(other: Any?): Boolean { + if (other !is Opt<*>) return false + if (value == null && other.value == null) return true + if( value == null || other.value == null) return false + return value == other.value + } + + val isNull by lazy { value == null } + val isNotNull by lazy { value != null } + + fun orElse(f: ()->T) = value ?: f() + + override fun toString(): String = "Opt[$value]" +} + diff --git a/src/jvmTest/kotlin/net/sergeych/parsec3/WsServerKtTest.kt b/src/jvmTest/kotlin/net/sergeych/parsec3/WsServerKtTest.kt index 0b993cf..e19ef82 100644 --- a/src/jvmTest/kotlin/net/sergeych/parsec3/WsServerKtTest.kt +++ b/src/jvmTest/kotlin/net/sergeych/parsec3/WsServerKtTest.kt @@ -4,17 +4,25 @@ import assertThrows import io.ktor.server.engine.* import io.ktor.server.netty.* import kotlinx.coroutines.runBlocking +import kotlinx.serialization.Serializable import net.sergeych.mp_logger.Log +import net.sergeych.tools.Opt import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertTrue internal class WsServerKtTest { data class TestSession(var buzz: String = "BuZZ"): WithAdapter() + @Serializable + data class TestStruct(val foobar: String) + object TestApiServer: CommandHost() { val foo by command() val ping by command() + val nullable1 by command>() + val nullable2 by command() } object TestApiClient: CommandHost() { val bar by command() @@ -45,6 +53,46 @@ internal class WsServerKtTest { client.close() } + } + @Test + fun testWsServerNullables() { + + embeddedServer(Netty, port = 8081) { + parsec3TransportServer( + TestApiServer, + ) { + newSession { TestSession() } + on(api.foo) { + it + buzz + "-foo" + } + on(api.nullable2) { + if( it ) null else "not null" + } + on(api.nullable1) { + if( it ) Opt(null) else Opt(TestStruct("not null")) + } + } + }.start(wait = false) + + val client = Parsec3WSClient("ws://localhost:8081/api/p3", TestApiClient) {} + + runBlocking { + val x = TestApiServer.foo.invoke(client.adapter(), "*great*") + assertEquals("*great*BuZZ-foo", x) + assertEquals(TestApiServer.nullable2.invoke(client.adapter(), true),null) + assertEquals(TestApiServer.nullable2.invoke(client.adapter(), false),"not null") + assertEquals(TestApiServer.nullable1.invoke(client.adapter(), true),Opt(null)) + + assertTrue { TestApiServer.nullable1.invoke(client.adapter(), true).isNull } + assertTrue { TestApiServer.nullable1.invoke(client.adapter(), false).isNotNull } + assertEquals(TestApiServer.nullable1.invoke(client.adapter(), false),Opt(TestStruct("not null"))) + assertTrue { TestApiServer.nullable1.invoke(client.adapter(), false).value == TestStruct("not null") } + client.close() + + assertEquals("bar", Opt("bar").orElse { "foobar" } ) + assertEquals("foobar", Opt(null).orElse { "foobar" } ) + } + } @Test fun testWsServerReconnect() {