diff --git a/README.md b/README.md index d4cddc9ff51d..26e6f3bf4b16 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ you to try out our library, we don't recommend you use this in production just y If you have any feedback, we'd love to hear it, hit us up on discord or write up an issue if you have any suggestions! -## What is Kord +## What is Kord? Kord is a [coroutine-based](https://kotlinlang.org/docs/reference/coroutines-overview.html), modularized implementation of the Discord API, written 100% in [Kotlin](https://kotlinlang.org/). @@ -26,28 +26,42 @@ unconventional things, and we want to allow you to do those in a safe and suppor ## Status of Kord -* [X] [Discord Gateway](https://github.com/kordlib/kord/tree/master/gateway) -* [x] [Discord Rest API](https://github.com/kordlib/kord/tree/master/rest) -* [X] [High level abstraction + caching](https://github.com/kordlib/kord/tree/master/core) -* [X] [Discord Voice](https://github.com/kordlib/kord/tree/master/voice) +* [X] [Discord Gateway](gateway) +* [x] [Discord Rest API](rest) +* [X] [High level abstraction + caching](core) +* [X] [Discord Voice](voice) * [ ] Support for multiple processes [#7](https://github.com/kordlib/kord/issues/7) -Right now Kord *should* provide a full mapping of the non-voice API. We're currently working on a testing library for -easy bot testing against a semi mocked client as well as our own command system to facilitate more complex bot -development. +Right now, Kord *should* provide a full mapping of the non-voice API on Kotlin/JVM and Kotlin/JS and an experimental +mapping of the Voice API on Kotlin/JVM ## Documentation * [Dokka docs](https://kordlib.github.io/kord/) * [Wiki](https://github.com/kordlib/kord/wiki) +## Modules + +| Module | Docs | Artifact | JVM | JS | Native² | +|--------------------------|---------------------------------------------------------|-------------------|-----|----|---------| +| [common](common) | [common](https://kordlib.github.io/kord/common) | `kord-common`¹ | ✅ | ✅ | ❌ | +| [rest](rest) | [rest](https://kordlib.github.io/kord/rest) | `kord-rest`¹ | ✅ | ✅ | ❌ | +| [gateway](gateway) | [gateway](https://kordlib.github.io/kord/gateway) | `kord-gateway`¹ | ✅ | ✅ | ❌ | +| [core](core) | [core](https://kordlib.github.io/kord/core) | `kord-core`¹ | ✅ | ✅ | ❌ | +| [voice](voice) | [voice](https://kordlib.github.io/kord/voice) | `kord-voice` | ✅ | ❌³ | ❌ | +| [core-voice](core-voice) | [core-voice](https://kordlib.github.io/kord/core-voice) | `kord-core-voice` | ✅ | ❌ | ❌ | + +¹ These artifacts only supports Gradle Version 5.3 or higher, for older Gradle versions and Maven please append `-jvm` +² For Native Support please see #69 +³ For Voice JS please see #69 + ## Installation Replace `{version}` with the latest version number on maven central. -For Snapshots replace `{version}` with `{branch}-SNAPSHOT` +For Snapshots replace `{version}` with `{branch}-SNAPSHOT` -e.g: `0.7.x-SNAPSHOT` +e.g: `0.9.x-SNAPSHOT` for the branch `0.9.x` or `feature-mpp-SNAPSHOT` for the branch `feature/mpp` [![Download](https://img.shields.io/maven-central/v/dev.kord/kord-core.svg?label=Maven%20Central&style=for-the-badge)](https://search.maven.org/search?q=g:%22dev.kord%22%20AND%20a:%22kord-core%22) @@ -111,129 +125,22 @@ dependencies { dev.kord - kord-core + kord-core-jvm {version} ``` -## Modules - -### Core - -A higher level API, combining `rest` and `gateway`, with additional (optional) caching. Unless you're writing your own -abstractions, we'd recommend using this. - -```kotlin -suspend fun main() { - val kord = Kord("your bot token") - val pingPong = ReactionEmoji.Unicode("\uD83C\uDFD3") - - kord.on { - if (message.content != "!ping") return@on - - val response = message.channel.createMessage("Pong!") - response.addReaction(pingPong) - - delay(5000) - message.delete() - response.delete() - } - - kord.login { - @OptIn(PrivilegedIntent::class) - intents += Intent.MessageContent - } -} -``` - -### Rest - -A low level mapping of Discord's REST API. Requests follow -Discord's [rate limits](https://discord.com/developers/docs/topics/rate-limits). - -```kotlin -suspend fun main() { - val rest = RestClient("your bot token") - val channelId = Snowflake(605212557522763787) - - rest.channel.createMessage(channelId) { - content = "Hello Kord!" - - embed { - color = Color(red = 0, green = 0, blue = 255) - description = "Hello embed!" - } - } -} -``` - -### Gateway - -A low level mapping of [Discord's Gateway](https://discord.com/developers/docs/topics/gateway), which maintains the -connection and rate limits commands. - -```kotlin -suspend fun main() { - val gateway = DefaultGateway() - - gateway.on { - println("${message.author.username}: ${message.content}") - val words = message.content.split(' ') - when (words.firstOrNull()) { - "!close" -> gateway.stop() - "!detach" -> gateway.detach() - } - } - - gateway.start("your bot token") { - @OptIn(PrivilegedIntent::class) - intents += Intent.MessageContent - } -} -``` - - -### Voice - -A mapping of [Discord's Voice Connection](https://discord.com/developers/docs/topics/voice-connections), which maintains the connection and handles audio transmission. - -If you want to use voice, you need to enable the voice capability, -which is only available for Gradle - -```kotlin -dependencies { - implementation("dev.kord", "core", "") { - capabilities { - requireCapability("dev.kord:core-voice:") - } - } -} -``` - -```kotlin -suspend fun main() { - val kord = Kord("your token") - val voiceChannel = kord.getChannelOf(id = Snowflake(1))!! - - voiceChannel.connect { - audioProvider { AudioFrame.fromData(/* your opus encoded audio */) } - } - - kord.login() -} -``` - ## FAQ ## Will you support kotlin multi-platform -We will, there's an [issue](https://github.com/kordlib/kord/issues/69) open to track the features we want/need to make a -transition to MPP smooth. +Currently we're supporting both Kotlin/JVM and Kotlin/JS for the majority of our API, for more information check +[Modules](#modules) and #69 -## When will you document your code +## When will you document your code? Yes. # This project is supported by JetBrains -[![JetBrains Logo (Main) logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://jb.gg/OpenSourceSupport) \ No newline at end of file +[![JetBrains Logo (Main) logo](https://resources.jetbrains.com/storage/products/company/brand/logos/jb_beam.svg)](https://jb.gg/OpenSourceSupport) diff --git a/buildSrc/src/main/kotlin/BinaryCompatibility.kt b/buildSrc/src/main/kotlin/BinaryCompatibility.kt new file mode 100644 index 000000000000..c457cea65e45 --- /dev/null +++ b/buildSrc/src/main/kotlin/BinaryCompatibility.kt @@ -0,0 +1,5 @@ +import kotlinx.validation.ApiValidationExtension + +fun ApiValidationExtension.applyKordBCVOptions() { + nonPublicMarkers += "dev.kord.common.annotation.KordInternal" +} diff --git a/buildSrc/src/main/kotlin/Compiler.kt b/buildSrc/src/main/kotlin/Compiler.kt index 382763bca8c7..3d4cc2614d16 100644 --- a/buildSrc/src/main/kotlin/Compiler.kt +++ b/buildSrc/src/main/kotlin/Compiler.kt @@ -1,21 +1,46 @@ -import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions +import kotlinx.atomicfu.plugin.gradle.AtomicFUPluginExtension +import org.gradle.api.Project +import org.gradle.api.artifacts.VersionCatalogsExtension +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.getByType +import org.jetbrains.kotlin.gradle.dsl.KotlinCommonCompilerOptions +import org.jetbrains.kotlin.gradle.plugin.KotlinSourceSet -object CompilerArguments { - const val time = "-opt-in=kotlin.time.ExperimentalTime" - const val contracts = "-opt-in=kotlin.contracts.ExperimentalContracts" +object OptIns { + const val coroutines = "kotlinx.coroutines.ExperimentalCoroutinesApi" +} - const val kordPreview = "-opt-in=dev.kord.common.annotation.KordPreview" - const val kordExperimental = "-opt-in=dev.kord.common.annotation.KordExperimental" - const val kordVoice = "-opt-in=dev.kord.common.annotation.KordVoice" +val kordOptIns = listOf( + "kotlin.time.ExperimentalTime", + "kotlin.contracts.ExperimentalContracts", - const val progressive = "-progressive" -} + "dev.kord.common.annotation.KordInternal", + "dev.kord.common.annotation.KordPreview", + "dev.kord.common.annotation.KordExperimental", + "dev.kord.common.annotation.KordVoice", +) object Jvm { const val target = 8 } -fun KotlinJvmCompilerOptions.applyKordCompilerOptions() { - allWarningsAsErrors.set(true) - freeCompilerArgs.add(CompilerArguments.progressive) +fun KotlinCommonCompilerOptions.applyKordCompilerOptions() { + // TODO: set to true again once https://github.com/Kotlin/kotlinx-atomicfu/issues/289 is fixed + allWarningsAsErrors.set(false) + freeCompilerArgs.add("-progressive") +} + +fun KotlinSourceSet.applyKordOptIns() { + languageSettings { + if ("Test" in name) optIn(OptIns.coroutines) + kordOptIns.forEach(::optIn) + } +} + +fun Project.configureAtomicFU() { + // https://github.com/Kotlin/kotlinx-atomicfu/issues/210 + configure { + val libs = extensions.getByType().named("libs") + dependenciesVersion = libs.findVersion("kotlinx-atomicfu").get().requiredVersion + } } diff --git a/buildSrc/src/main/kotlin/Documentation.kt b/buildSrc/src/main/kotlin/Documentation.kt new file mode 100644 index 000000000000..db5da77659e5 --- /dev/null +++ b/buildSrc/src/main/kotlin/Documentation.kt @@ -0,0 +1,33 @@ +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask +import java.net.URL + +fun AbstractDokkaLeafTask.applyKordDokkaOptions() { + failOnWarning.set(true) + + dokkaSourceSets.configureEach { + + jdkVersion.set(Jvm.target) + + suppressGeneratedFiles.set(false) + + sourceLink { + localDirectory.set(project.projectDir) + remoteUrl.set(URL("https://github.com/kordlib/kord/blob/${Library.commitHashOrDefault("0.9.x")}/${project.name}")) + remoteLineSuffix.set("#L") + } + + externalDocumentationLink("https://kotlinlang.org/api/kotlinx.coroutines/") + externalDocumentationLink("https://kotlinlang.org/api/kotlinx.serialization/") + externalDocumentationLink( + url = "https://kotlinlang.org/api/kotlinx-datetime/", + packageListUrl = "https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/package-list", + ) + externalDocumentationLink("https://api.ktor.io/") + + // don't list `TweetNaclFast` in docs + perPackageOption { + matchingRegex.set("""com\.iwebpp\.crypto""") + suppress.set(true) + } + } +} diff --git a/buildSrc/src/main/kotlin/kord-internal-multiplatform-module.gradle.kts b/buildSrc/src/main/kotlin/kord-internal-multiplatform-module.gradle.kts new file mode 100644 index 000000000000..53be19854869 --- /dev/null +++ b/buildSrc/src/main/kotlin/kord-internal-multiplatform-module.gradle.kts @@ -0,0 +1,23 @@ +plugins { + org.jetbrains.kotlin.multiplatform +} + +repositories { + mavenCentral() +} + +kotlin { + jvm() + js(IR) { + nodejs() + } + jvmToolchain(Jvm.target) + + targets { + all { + compilations.all { + compilerOptions.options.applyKordCompilerOptions() + } + } + } +} diff --git a/buildSrc/src/main/kotlin/kord-module.gradle.kts b/buildSrc/src/main/kotlin/kord-module.gradle.kts index 37b6d0dab5b1..1c7608680a4b 100644 --- a/buildSrc/src/main/kotlin/kord-module.gradle.kts +++ b/buildSrc/src/main/kotlin/kord-module.gradle.kts @@ -1,7 +1,5 @@ -import com.google.devtools.ksp.gradle.KspTask import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask import org.jetbrains.kotlin.gradle.tasks.KotlinCompile -import java.net.URL plugins { org.jetbrains.kotlin.jvm @@ -17,38 +15,32 @@ repositories { mavenCentral() } +dependencies { + ksp(project(":ksp-processors")) +} + +apiValidation { + applyKordBCVOptions() +} + kotlin { explicitApi() jvmToolchain(Jvm.target) sourceSets { - // mark ksp src dir - main { kotlin.srcDir("build/generated/ksp/main/kotlin") } - // allow `ExperimentalCoroutinesApi` for `runTest {}` - test { languageSettings.optIn("kotlinx.coroutines.ExperimentalCoroutinesApi") } + test { languageSettings.optIn(OptIns.coroutines) } } } -// https://github.com/Kotlin/kotlinx-atomicfu/issues/210 -atomicfu { - val libs = extensions.getByType().named("libs") - dependenciesVersion = libs.findVersion("kotlinx-atomicfu").get().requiredVersion -} +configureAtomicFU() tasks { - withType { + withType().configureEach { compilerOptions { applyKordCompilerOptions() - freeCompilerArgs.addAll( - CompilerArguments.time, - CompilerArguments.contracts, - - CompilerArguments.kordPreview, - CompilerArguments.kordExperimental, - CompilerArguments.kordVoice, - ) + freeCompilerArgs.addAll(kordOptIns.map { "-opt-in=$it" }) } } @@ -56,80 +48,18 @@ tasks { useJUnitPlatform() } - fun Task.dependsOnKspKotlin() { - val kspKotlin = findByName("kspKotlin") - if (kspKotlin != null) dependsOn(kspKotlin) - } - - // configure both dokkaHtml and dokkaHtmlPartial tasks - // (dokkaHtmlMultiModule depends on dokkaHtmlPartial, dokkaJar depends on dokkaHtml) withType().configureEach { - // see https://kotlin.github.io/dokka//user_guide/gradle/usage/#configuration-options - - // include documentation generated by ksp - dependsOnKspKotlin() - - failOnWarning.set(true) - - dokkaSourceSets.configureEach { - - jdkVersion.set(Jvm.target) - - val baseRemoteUrl = - "https://github.com/kordlib/kord/blob/${Library.commitHashOrDefault("0.9.x")}/${project.name}" - - sourceLink { - localDirectory.set(file("src/main/kotlin")) - remoteUrl.set(URL("$baseRemoteUrl/src/main/kotlin")) - remoteLineSuffix.set("#L") - } - - // config for files generated by ksp - suppressGeneratedFiles.set(false) - sourceLink { - // will fail if dir doesn't exist -> always create it, won't harm if not needed - localDirectory.set(file("build/generated/ksp/main/kotlin").apply { mkdirs() }) - remoteUrl.set(URL("$baseRemoteUrl/build/generated/ksp/main/kotlin")) - remoteLineSuffix.set("#L") - } - - externalDocumentationLink("https://kotlinlang.org/api/kotlinx.coroutines/") - externalDocumentationLink("https://kotlinlang.org/api/kotlinx.serialization/") - externalDocumentationLink( - url = "https://kotlinlang.org/api/kotlinx-datetime/", - packageListUrl = "https://kotlinlang.org/api/kotlinx-datetime/kotlinx-datetime/package-list", - ) - externalDocumentationLink("https://api.ktor.io/") - - // don't list `TweetNaclFast` in docs - perPackageOption { - matchingRegex.set("""com\.iwebpp\.crypto""") - suppress.set(true) - } - } + applyKordDokkaOptions() } withType().configureEach { doFirst { require(!Library.isUndefined) { "No release/snapshot version found." } } } - - kotlinSourcesJar { - // include sources generated by ksp - dependsOnKspKotlin() - } -} - -val dokkaJar by tasks.registering(Jar::class) { - group = JavaBasePlugin.DOCUMENTATION_GROUP - description = "Assembles Kotlin docs with Dokka" - archiveClassifier.set("javadoc") - from(tasks.dokkaHtml) } publishing { - publications.withType().configureEach { + publications.register(Library.name) { from(components["java"]) artifact(tasks.kotlinSourcesJar) - artifact(dokkaJar) } } diff --git a/buildSrc/src/main/kotlin/kord-multiplatform-module.gradle.kts b/buildSrc/src/main/kotlin/kord-multiplatform-module.gradle.kts new file mode 100644 index 000000000000..b33a4e65cfc6 --- /dev/null +++ b/buildSrc/src/main/kotlin/kord-multiplatform-module.gradle.kts @@ -0,0 +1,88 @@ +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask +import org.jetbrains.kotlin.gradle.targets.js.testing.KotlinJsTest + +plugins { + org.jetbrains.kotlin.multiplatform + org.jetbrains.kotlin.plugin.serialization + org.jetbrains.dokka + `kotlinx-atomicfu` + org.jetbrains.kotlinx.`binary-compatibility-validator` + com.google.devtools.ksp +} + +repositories { + mavenCentral() +} + +dependencies { + kspCommonMainMetadata(project(":ksp-processors")) +} + +apiValidation { + applyKordBCVOptions() +} + +kotlin { + explicitApi() + + jvm() + js(IR) { + nodejs() + } + jvmToolchain(Jvm.target) + + targets.all { + compilations.all { + compilerOptions.options.applyKordCompilerOptions() + } + } + + sourceSets { + all { + applyKordOptIns() + } + commonMain { + // mark ksp src dir + kotlin.srcDir("build/generated/ksp/metadata/commonMain/kotlin") + } + commonTest { + dependencies { + implementation(project(":test-kit")) + } + } + val nonJvmMain by creating { + dependsOn(commonMain.get()) + } + targets + .map { it.name } + .filter { it != "jvm" && it != "metadata" } + .forEach { target -> + sourceSets.getByName("${target}Main") { + dependsOn(nonJvmMain) + } + } + } +} + +configureAtomicFU() + +tasks { + withType().configureEach { + useJUnitPlatform() + } + + withType().configureEach { + environment("PROJECT_ROOT", rootProject.projectDir.absolutePath) + } + + for (task in listOf("compileKotlinJvm", "compileKotlinJs", "jvmSourcesJar", "jsSourcesJar")) { + named(task) { + dependsOn("kspCommonMainKotlinMetadata") + } + } + + withType().configureEach { + applyKordDokkaOptions() + dependsOn("kspCommonMainKotlinMetadata") + } +} diff --git a/buildSrc/src/main/kotlin/kord-publishing.gradle.kts b/buildSrc/src/main/kotlin/kord-publishing.gradle.kts index f080e6714f13..593dd1348b86 100644 --- a/buildSrc/src/main/kotlin/kord-publishing.gradle.kts +++ b/buildSrc/src/main/kotlin/kord-publishing.gradle.kts @@ -5,11 +5,17 @@ plugins { signing } +val dokkaJar by tasks.registering(Jar::class) { + archiveClassifier.set("javadoc") + from(tasks.named("dokkaHtml")) +} + publishing { publications { - create(Library.name) { + withType().configureEach { + artifact(dokkaJar) groupId = Library.group - artifactId = "kord-${project.name}" + artifactId = "kord-$artifactId" version = Library.version pom { @@ -46,17 +52,17 @@ publishing { url.set(Library.projectUrl) } } + } + } - if (!isJitPack) { - repositories { - maven { - url = uri(if (Library.isSnapshot) Repo.snapshotsUrl else Repo.releasesUrl) + if (!isJitPack) { + repositories { + maven { + url = uri(if (Library.isSnapshot) Repo.snapshotsUrl else Repo.releasesUrl) - credentials { - username = System.getenv("NEXUS_USER") - password = System.getenv("NEXUS_PASSWORD") - } - } + credentials { + username = System.getenv("NEXUS_USER") + password = System.getenv("NEXUS_PASSWORD") } } } diff --git a/common/api/common.api b/common/api/common.api index 81a0b0d6a681..42028ff4097b 100644 --- a/common/api/common.api +++ b/common/api/common.api @@ -102,7 +102,6 @@ public final class dev/kord/common/Locale { public static final field Companion Ldev/kord/common/Locale$Companion; public fun (Ljava/lang/String;Ljava/lang/String;)V public synthetic fun (Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;)V - public final fun asJavaLocale ()Ljava/util/Locale; public final fun component1 ()Ljava/lang/String; public final fun component2 ()Ljava/lang/String; public final fun copy (Ljava/lang/String;Ljava/lang/String;)Ldev/kord/common/Locale; @@ -161,6 +160,7 @@ public final class dev/kord/common/Locale$Serializer : kotlinx/serialization/KSe } public final class dev/kord/common/LocaleKt { + public static final fun asJavaLocale (Ldev/kord/common/Locale;)Ljava/util/Locale; public static final fun getKLocale (Ljava/util/Locale;)Ldev/kord/common/Locale; } @@ -174,6 +174,9 @@ public abstract interface annotation class dev/kord/common/annotation/KordDsl : public abstract interface annotation class dev/kord/common/annotation/KordExperimental : java/lang/annotation/Annotation { } +public abstract interface annotation class dev/kord/common/annotation/KordInternal : java/lang/annotation/Annotation { +} + public abstract interface annotation class dev/kord/common/annotation/KordPreview : java/lang/annotation/Annotation { } diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 270b4b897d91..3975a46823f0 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -1,22 +1,46 @@ @Suppress("DSL_SCOPE_VIOLATION") // false positive for `libs` in IntelliJ plugins { - `kord-module` - `kord-sampled-module` + `kord-multiplatform-module` `kord-publishing` alias(libs.plugins.buildconfig) } -dependencies { - api(libs.kotlinx.coroutines.core) - api(libs.kotlinx.serialization.json) - api(libs.kotlinx.datetime) - api(libs.kotlin.logging) +kotlin { + sourceSets { + commonMain { + dependencies { + api(libs.kotlinx.coroutines.core) + api(libs.kotlinx.serialization.json) + api(libs.kotlinx.datetime) + api(libs.kotlin.logging) - compileOnly(projects.kspAnnotations) - ksp(projects.kspProcessors) + api(libs.ktor.client.core) - testImplementation(libs.bundles.test.implementation) - testRuntimeOnly(libs.bundles.test.runtime) + compileOnly(projects.kspAnnotations) + } + } + jvmMain { + dependencies { + api(libs.ktor.client.cio) + } + } + nonJvmMain { + dependencies { + implementation(libs.ktor.utils) + implementation(libs.bignum) + implementation(libs.stately.collections) + } + } + jsMain { + dependencies { + api(libs.ktor.client.js) + + // workaround for https://youtrack.jetbrains.com/issue/KT-43500 + // (intended to be compileOnly in commonMain only) + implementation(projects.kspAnnotations) + } + } + } } /* diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AllowedMentionType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AllowedMentionType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AllowedMentionType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AllowedMentionType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandOptionType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandOptionType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandOptionType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandOptionType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandPermissionType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandPermissionType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandPermissionType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandPermissionType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ApplicationCommandType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ApplicationCommandType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AuditLogEvent.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AuditLogEvent.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AuditLogEvent.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AuditLogEvent.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationActionType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationActionType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationActionType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationActionType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleEventType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleEventType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleEventType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleEventType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleKeywordPresetType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleKeywordPresetType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleKeywordPresetType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleKeywordPresetType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleTriggerType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleTriggerType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/AutoModerationRuleTriggerType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/AutoModerationRuleTriggerType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ButtonStyle.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ButtonStyle.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ButtonStyle.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ButtonStyle.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ChannelType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ChannelType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ChannelType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ChannelType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ComponentType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ComponentType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ComponentType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ComponentType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/DefaultMessageNotificationLevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/DefaultMessageNotificationLevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/DefaultMessageNotificationLevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/DefaultMessageNotificationLevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/DiscordConnectionVisibility.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/DiscordConnectionVisibility.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/DiscordConnectionVisibility.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/DiscordConnectionVisibility.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/EmbedType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/EmbedType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/EmbedType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/EmbedType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ExplicitContentFilter.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ExplicitContentFilter.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ExplicitContentFilter.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ExplicitContentFilter.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ForumLayoutType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ForumLayoutType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ForumLayoutType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ForumLayoutType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildFeature.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildFeature.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildFeature.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildFeature.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildScheduledEventPrivacyLevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildScheduledEventPrivacyLevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildScheduledEventPrivacyLevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildScheduledEventPrivacyLevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildScheduledEventStatus.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildScheduledEventStatus.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/GuildScheduledEventStatus.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/GuildScheduledEventStatus.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/IntegrationExpireBehavior.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/IntegrationExpireBehavior.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/IntegrationExpireBehavior.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/IntegrationExpireBehavior.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InteractionResponseType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InteractionResponseType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InteractionResponseType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InteractionResponseType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InteractionType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InteractionType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InteractionType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InteractionType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InviteTargetType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InviteTargetType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/InviteTargetType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/InviteTargetType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MFALevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MFALevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MFALevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MFALevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageActivityType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageActivityType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageActivityType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageActivityType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageStickerType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageStickerType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageStickerType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageStickerType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/MessageType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/MessageType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/NsfwLevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/NsfwLevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/NsfwLevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/NsfwLevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/OnboardingPromptType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/OnboardingPromptType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/OnboardingPromptType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/OnboardingPromptType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/OverwriteType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/OverwriteType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/OverwriteType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/OverwriteType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/PremiumTier.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/PremiumTier.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/PremiumTier.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/PremiumTier.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/PresenceStatus.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/PresenceStatus.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/PresenceStatus.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/PresenceStatus.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ScheduledEntityType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ScheduledEntityType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/ScheduledEntityType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/ScheduledEntityType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/SortOrderType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/SortOrderType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/SortOrderType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/SortOrderType.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/StageInstancePrivacyLevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/StageInstancePrivacyLevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/StageInstancePrivacyLevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/StageInstancePrivacyLevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/TeamMembershipState.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/TeamMembershipState.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/TeamMembershipState.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/TeamMembershipState.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/TextInputStyle.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/TextInputStyle.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/TextInputStyle.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/TextInputStyle.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/UserPremium.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/UserPremium.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/UserPremium.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/VerificationLevel.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/VerificationLevel.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/VerificationLevel.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/VerificationLevel.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/VideoQualityMode.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/VideoQualityMode.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/VideoQualityMode.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/VideoQualityMode.kt diff --git a/common/build/generated/ksp/main/kotlin/dev/kord/common/entity/WebhookType.kt b/common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/WebhookType.kt similarity index 100% rename from common/build/generated/ksp/main/kotlin/dev/kord/common/entity/WebhookType.kt rename to common/build/generated/ksp/metadata/commonMain/kotlin/dev/kord/common/entity/WebhookType.kt diff --git a/common/src/main/kotlin/Color.kt b/common/src/commonMain/kotlin/Color.kt similarity index 78% rename from common/src/main/kotlin/Color.kt rename to common/src/commonMain/kotlin/Color.kt index c45381954b26..b7fed9e74852 100644 --- a/common/src/main/kotlin/Color.kt +++ b/common/src/commonMain/kotlin/Color.kt @@ -36,6 +36,17 @@ public class Color(rgb: Int) { public companion object { private const val MIN_COLOR = 0 private const val MAX_COLOR = 0xFFFFFF + + private fun rgb(red: Int, green: Int, blue: Int): Int { + require(red in 0..255) { "Red should be in range of 0..255 but was $red" } + require(green in 0..255) { "Green should be in range of 0..255 but was $green" } + require(blue in 0..255) { "Blue should be in range of 0..255 but was $blue" } + + + return red and 0xFF shl 16 or + (green and 0xFF shl 8) or + (blue and 0xFF) shl 0 + } } internal object Serializer : KSerializer { @@ -49,16 +60,3 @@ public class Color(rgb: Int) { } } } - -private fun rgb(red: Int, green: Int, blue: Int): Int { - require(red in 0..255) { "Red should be in range of 0..255 but was $red" } - require(green in 0..255) { "Green should be in range of 0..255 but was $green" } - require(blue in 0..255) { "Blue should be in range of 0..255 but was $blue" } - - - return red and 0xFF shl 16 or - (green and 0xFF shl 8) or - (blue and 0xFF) shl 0 -} - -public val java.awt.Color.kColor: Color get() = Color(rgb) diff --git a/common/src/commonMain/kotlin/ConcurrentHashMap.kt b/common/src/commonMain/kotlin/ConcurrentHashMap.kt new file mode 100644 index 000000000000..6e0ea0791fb5 --- /dev/null +++ b/common/src/commonMain/kotlin/ConcurrentHashMap.kt @@ -0,0 +1,11 @@ +package dev.kord.common + +import dev.kord.common.annotation.KordInternal + +/** + * Platform-agnostic implementation of ConcurrentHashMap. + * + * @suppress + */ +@KordInternal +public expect class ConcurrentHashMap() : MutableMap diff --git a/common/src/main/kotlin/DiscordBitSet.kt b/common/src/commonMain/kotlin/DiscordBitSet.kt similarity index 91% rename from common/src/main/kotlin/DiscordBitSet.kt rename to common/src/commonMain/kotlin/DiscordBitSet.kt index 17ebcffb2c44..8098026c4701 100644 --- a/common/src/main/kotlin/DiscordBitSet.kt +++ b/common/src/commonMain/kotlin/DiscordBitSet.kt @@ -7,8 +7,6 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.math.BigInteger -import java.nio.ByteBuffer import kotlin.math.max import kotlin.math.min @@ -18,19 +16,16 @@ private const val WIDTH = Long.SIZE_BITS @Suppress("FunctionName") public fun EmptyBitSet(): DiscordBitSet = DiscordBitSet() +internal expect fun formatIntegerFromLittleEndianLongArray(data: LongArray): String +internal expect fun parseIntegerToBigEndianByteArray(value: String): ByteArray + @Serializable(with = DiscordBitSetSerializer::class) public class DiscordBitSet(internal var data: LongArray) { // data is in little-endian order public val isEmpty: Boolean get() = data.all { it == 0L } - public val value: String - get() { - // need to convert from little-endian data to big-endian expected by BigInteger - val buffer = ByteBuffer.allocate(data.size * Long.SIZE_BYTES) - buffer.asLongBuffer().put(data.reversedArray()) - return BigInteger(buffer.array()).toString() - } + public val value: String get() = formatIntegerFromLittleEndianLongArray(data) public val size: Int get() = data.size * WIDTH @@ -128,7 +123,7 @@ public fun DiscordBitSet(value: String): DiscordBitSet { return DiscordBitSet(longArrayOf(value.toULong().toLong())) } - val bytes = BigInteger(value).toByteArray() + val bytes = parseIntegerToBigEndianByteArray(value) val longSize = (bytes.size / Long.SIZE_BYTES) + 1 val destination = LongArray(longSize) diff --git a/common/src/main/kotlin/DiscordTimestamp.kt b/common/src/commonMain/kotlin/DiscordTimestamp.kt similarity index 100% rename from common/src/main/kotlin/DiscordTimestamp.kt rename to common/src/commonMain/kotlin/DiscordTimestamp.kt diff --git a/common/src/main/kotlin/KordConfiguration.kt b/common/src/commonMain/kotlin/KordConfiguration.kt similarity index 100% rename from common/src/main/kotlin/KordConfiguration.kt rename to common/src/commonMain/kotlin/KordConfiguration.kt diff --git a/common/src/main/kotlin/KordConstants.kt b/common/src/commonMain/kotlin/KordConstants.kt similarity index 100% rename from common/src/main/kotlin/KordConstants.kt rename to common/src/commonMain/kotlin/KordConstants.kt diff --git a/common/src/main/kotlin/Locale.kt b/common/src/commonMain/kotlin/Locale.kt similarity index 95% rename from common/src/main/kotlin/Locale.kt rename to common/src/commonMain/kotlin/Locale.kt index 63e922ddb2ed..9b45e530cdd8 100644 --- a/common/src/main/kotlin/Locale.kt +++ b/common/src/commonMain/kotlin/Locale.kt @@ -7,7 +7,6 @@ import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder -import java.util.Locale as JLocale /** * Representation of a locale [supported by Discord](https://discord.com/developers/docs/reference#locales). @@ -17,11 +16,6 @@ import java.util.Locale as JLocale */ @Serializable(with = Locale.Serializer::class) public data class Locale(val language: String, val country: String? = null) { - /** - * Converts this into a [JLocale]. - */ - public fun asJavaLocale(): JLocale = JLocale(language, country ?: "") - public companion object { /** @@ -247,9 +241,3 @@ public data class Locale(val language: String, val country: String? = null) { override fun deserialize(decoder: Decoder): Locale = fromString(decoder.decodeString()) } } - -/** - * Converts this into a [Locale]. - */ -public val JLocale.kLocale: Locale - get() = Locale(language, country.ifBlank { null }) diff --git a/common/src/main/kotlin/annotation/Annotations.kt b/common/src/commonMain/kotlin/annotation/Annotations.kt similarity index 85% rename from common/src/main/kotlin/annotation/Annotations.kt rename to common/src/commonMain/kotlin/annotation/Annotations.kt index ee5107389a4b..c3355c01d84c 100644 --- a/common/src/main/kotlin/annotation/Annotations.kt +++ b/common/src/commonMain/kotlin/annotation/Annotations.kt @@ -1,12 +1,13 @@ package dev.kord.common.annotation +import kotlin.RequiresOptIn.Level.ERROR import kotlin.RequiresOptIn.Level.WARNING -import kotlin.annotation.AnnotationRetention.RUNTIME +import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationTarget.* /** [DslMarker] for Kord DSLs. */ @DslMarker -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS) public annotation class KordDsl @@ -20,7 +21,7 @@ public annotation class KordDsl */ @MustBeDocumented @RequiresOptIn(level = WARNING) -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, PROPERTY, CONSTRUCTOR, FUNCTION, TYPEALIAS) public annotation class KordPreview @@ -35,7 +36,7 @@ public annotation class KordPreview */ @MustBeDocumented @RequiresOptIn(level = WARNING) -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, PROPERTY, FUNCTION, TYPEALIAS) public annotation class KordExperimental @@ -50,7 +51,7 @@ public annotation class KordExperimental */ @MustBeDocumented @RequiresOptIn(level = WARNING) -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, PROPERTY, FUNCTION, TYPEALIAS) public annotation class KordVoice @@ -66,7 +67,7 @@ public annotation class KordVoice */ @MustBeDocumented @RequiresOptIn("This API is potentially unsafe.", level = WARNING) -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, PROPERTY, FUNCTION, PROPERTY_SETTER, TYPEALIAS) public annotation class KordUnsafe @@ -76,6 +77,15 @@ public annotation class KordUnsafe * These declarations must also be annotated with [Deprecated]. */ @MustBeDocumented -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, ANNOTATION_CLASS, PROPERTY, CONSTRUCTOR, FUNCTION, PROPERTY_GETTER, PROPERTY_SETTER, TYPEALIAS) public annotation class DeprecatedSinceKord(val version: String) + +/** + * Marks an API for internal use only. + */ +@MustBeDocumented +@RequiresOptIn("This API is intended for internal use only.", level = ERROR) +@Retention(BINARY) +@Target(CLASS, PROPERTY, FUNCTION, TYPEALIAS) +public annotation class KordInternal diff --git a/common/src/main/kotlin/entity/AuditLog.kt b/common/src/commonMain/kotlin/entity/AuditLog.kt similarity index 84% rename from common/src/main/kotlin/entity/AuditLog.kt rename to common/src/commonMain/kotlin/entity/AuditLog.kt index 5dc4b4365161..dce82c8c9751 100644 --- a/common/src/main/kotlin/entity/AuditLog.kt +++ b/common/src/commonMain/kotlin/entity/AuditLog.kt @@ -72,6 +72,7 @@ import dev.kord.ksp.GenerateKordEnum.Entry import dev.kord.ksp.GenerateKordEnum.ValueType.INT import kotlinx.datetime.Instant import kotlinx.serialization.* +import kotlinx.serialization.builtins.ListSerializer import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.* import kotlinx.serialization.encoding.* @@ -237,147 +238,156 @@ public sealed class AuditLogChangeKey(public val name: String, public val ser public class Unknown(name: String) : AuditLogChangeKey(name, JsonElement.serializer()) @SerialName("name") - public object Name : AuditLogChangeKey("name", serializer()) + public object Name : AuditLogChangeKey("name", String.serializer()) @SerialName("icon_hash") - public object IconHash : AuditLogChangeKey("icon_hash", serializer()) + public object IconHash : AuditLogChangeKey("icon_hash", String.serializer()) @SerialName("image_hash") - public object ImageHash : AuditLogChangeKey("image_hash", serializer()) + public object ImageHash : AuditLogChangeKey("image_hash", String.serializer()) @SerialName("splash_hash") - public object SplashHash : AuditLogChangeKey("splash_hash", serializer()) + public object SplashHash : AuditLogChangeKey("splash_hash", String.serializer()) @SerialName("owner_id") - public object OwnerId : AuditLogChangeKey("owner_id", serializer()) + public object OwnerId : AuditLogChangeKey("owner_id", Snowflake.serializer()) @SerialName("region") - public object Region : AuditLogChangeKey("region", serializer()) + public object Region : AuditLogChangeKey("region", String.serializer()) @SerialName("afk_channel_id") - public object AfkChannelId : AuditLogChangeKey("afk_channel_id", serializer()) + public object AfkChannelId : AuditLogChangeKey("afk_channel_id", Snowflake.serializer()) @SerialName("afk_timeout") public object AfkTimeout : AuditLogChangeKey("afk_timeout", DurationInSecondsSerializer) @SerialName("mfa_level") - public object MFALevel : AuditLogChangeKey("mfa_level", serializer()) + public object MFALevel : AuditLogChangeKey("mfa_level", CommonMFALevel.serializer()) @SerialName("verification_level") - public object VerificationLevel : AuditLogChangeKey("verification_level", serializer()) + public object VerificationLevel : + AuditLogChangeKey("verification_level", CommonVerificationLevel.serializer()) @SerialName("explicit_content_filter") - public object ExplicitContentFilter : - AuditLogChangeKey("explicit_content_filter", serializer()) + public object ExplicitContentFilter : AuditLogChangeKey( + "explicit_content_filter", + CommonExplicitContentFilter.serializer() + ) @SerialName("default_message_notifications") - public object DefaultMessageNotificationLevel : - AuditLogChangeKey("default_message_notifications", serializer()) + public object DefaultMessageNotificationLevel : AuditLogChangeKey( + "default_message_notifications", + CommonDefaultMessageNotificationLevel.serializer() + ) @SerialName("vanity_url_code") - public object VanityUrlCode : AuditLogChangeKey("vanity_url_code", serializer()) + public object VanityUrlCode : AuditLogChangeKey("vanity_url_code", String.serializer()) @SerialName("\$add") - public object Add : AuditLogChangeKey>("\$add", serializer()) + public object Add : + AuditLogChangeKey>("\$add", ListSerializer(DiscordPartialRole.serializer())) @SerialName("\$remove") - public object Remove : AuditLogChangeKey>("\$remove", serializer()) + public object Remove : + AuditLogChangeKey>("\$remove", ListSerializer(DiscordPartialRole.serializer())) @SerialName("prune_delete_days") - public object PruneDeleteDays : AuditLogChangeKey("prune_delete_days", serializer()) + public object PruneDeleteDays : AuditLogChangeKey("prune_delete_days", Int.serializer()) @SerialName("widget_enabled") - public object WidgetEnabled : AuditLogChangeKey("widget_enabled", serializer()) + public object WidgetEnabled : AuditLogChangeKey("widget_enabled", Boolean.serializer()) @SerialName("widget_channel_id") - public object WidgetChannelId : AuditLogChangeKey("widget_channel_id", serializer()) + public object WidgetChannelId : AuditLogChangeKey("widget_channel_id", Snowflake.serializer()) @SerialName("system_channel_id") - public object SystemChannelId : AuditLogChangeKey("system_channel_id", serializer()) + public object SystemChannelId : AuditLogChangeKey("system_channel_id", Snowflake.serializer()) @SerialName("position") - public object Position : AuditLogChangeKey("position", serializer()) + public object Position : AuditLogChangeKey("position", Int.serializer()) @SerialName("topic") - public object Topic : AuditLogChangeKey("topic", serializer()) + public object Topic : AuditLogChangeKey("topic", String.serializer()) @SerialName("bitrate") - public object Bitrate : AuditLogChangeKey("bitrate", serializer()) + public object Bitrate : AuditLogChangeKey("bitrate", Int.serializer()) @SerialName("permission_overwrites") - public object PermissionOverwrites : AuditLogChangeKey>("permission_overwrites", serializer()) + public object PermissionOverwrites : + AuditLogChangeKey>("permission_overwrites", ListSerializer(Overwrite.serializer())) @SerialName("nsfw") - public object Nsfw : AuditLogChangeKey("nsfw", serializer()) + public object Nsfw : AuditLogChangeKey("nsfw", Boolean.serializer()) @SerialName("application_id") - public object ApplicationId : AuditLogChangeKey("application_id", serializer()) + public object ApplicationId : AuditLogChangeKey("application_id", Snowflake.serializer()) @SerialName("rate_limit_per_user") public object RateLimitPerUser : AuditLogChangeKey("rate_limit_per_user", DurationInSecondsSerializer) @SerialName("permissions") - public object Permissions : AuditLogChangeKey("permissions", serializer()) + public object Permissions : AuditLogChangeKey("permissions", CommonPermissions.serializer()) @SerialName("color") - public object Color : AuditLogChangeKey("color", serializer()) + public object Color : AuditLogChangeKey("color", CommonColor.serializer()) @SerialName("command_id") - public object CommandId : AuditLogChangeKey("command_id", serializer()) + public object CommandId : AuditLogChangeKey("command_id", Snowflake.serializer()) @SerialName("communication_disabled_until") - public object CommunicationDisabledUntil : AuditLogChangeKey("communication_disabled_until", serializer()) + public object CommunicationDisabledUntil : + AuditLogChangeKey("communication_disabled_until", Instant.serializer()) @SerialName("hoist") - public object Hoist : AuditLogChangeKey("hoist", serializer()) + public object Hoist : AuditLogChangeKey("hoist", Boolean.serializer()) @SerialName("mentionable") - public object Mentionable : AuditLogChangeKey("mentionable", serializer()) + public object Mentionable : AuditLogChangeKey("mentionable", Boolean.serializer()) @SerialName("allow") - public object Allow : AuditLogChangeKey("allow", serializer()) + public object Allow : AuditLogChangeKey("allow", CommonPermissions.serializer()) @SerialName("deny") - public object Deny : AuditLogChangeKey("deny", serializer()) + public object Deny : AuditLogChangeKey("deny", CommonPermissions.serializer()) @SerialName("code") - public object Code : AuditLogChangeKey("code", serializer()) + public object Code : AuditLogChangeKey("code", String.serializer()) @SerialName("channel_id") - public object ChannelId : AuditLogChangeKey("channel_id", serializer()) + public object ChannelId : AuditLogChangeKey("channel_id", Snowflake.serializer()) @SerialName("inviter_id") - public object InviterId : AuditLogChangeKey("inviter_id", serializer()) + public object InviterId : AuditLogChangeKey("inviter_id", Snowflake.serializer()) @SerialName("location") - public object Location : AuditLogChangeKey("location", serializer()) + public object Location : AuditLogChangeKey("location", String.serializer()) @SerialName("max_uses") - public object MaxUses : AuditLogChangeKey("max_uses", serializer()) + public object MaxUses : AuditLogChangeKey("max_uses", Int.serializer()) @SerialName("uses") - public object Uses : AuditLogChangeKey("uses", serializer()) + public object Uses : AuditLogChangeKey("uses", Int.serializer()) @SerialName("max_age") public object MaxAges : AuditLogChangeKey("max_age", DurationInSecondsSerializer) @SerialName("temporary") - public object Temporary : AuditLogChangeKey("temporary", serializer()) + public object Temporary : AuditLogChangeKey("temporary", Boolean.serializer()) @SerialName("deaf") - public object Deaf : AuditLogChangeKey("deaf", serializer()) + public object Deaf : AuditLogChangeKey("deaf", Boolean.serializer()) @SerialName("mute") - public object Mute : AuditLogChangeKey("mute", serializer()) + public object Mute : AuditLogChangeKey("mute", Boolean.serializer()) @SerialName("nick") - public object Nick : AuditLogChangeKey("nick", serializer()) + public object Nick : AuditLogChangeKey("nick", String.serializer()) @SerialName("avatar_hash") - public object AvatarHash : AuditLogChangeKey("avatar_hash", serializer()) + public object AvatarHash : AuditLogChangeKey("avatar_hash", String.serializer()) @SerialName("id") - public object Id : AuditLogChangeKey("id", serializer()) + public object Id : AuditLogChangeKey("id", Snowflake.serializer()) /** * The actual supertype is [AuditLogChangeKey][AuditLogChangeKey] but Kotlin does not support union @@ -390,47 +400,41 @@ public sealed class AuditLogChangeKey(public val name: String, public val ser public object Type : AuditLogChangeKey("type", LongOrStringSerializer) @SerialName("enable_emoticons") - public object EnableEmoticons : AuditLogChangeKey("enable_emoticons", serializer()) + public object EnableEmoticons : AuditLogChangeKey("enable_emoticons", Boolean.serializer()) @SerialName("expire_behavior") - public object ExpireBehavior : AuditLogChangeKey("expire_behavior", serializer()) + public object ExpireBehavior : + AuditLogChangeKey("expire_behavior", IntegrationExpireBehavior.serializer()) @SerialName("expire_grace_period") public object ExpireGracePeriod : AuditLogChangeKey("expire_grace_period", DurationInDaysSerializer) @SerialName("user_limit") - public object UserLimit : AuditLogChangeKey("user_limit", serializer()) + public object UserLimit : AuditLogChangeKey("user_limit", Int.serializer()) @SerialName("archived") - public object Archived : AuditLogChangeKey("archived", serializer()) + public object Archived : AuditLogChangeKey("archived", Boolean.serializer()) @SerialName("locked") - public object Locked : AuditLogChangeKey("locked", serializer()) + public object Locked : AuditLogChangeKey("locked", Boolean.serializer()) @SerialName("auto_archive_duration") - public object AutoArchiveDuration : AuditLogChangeKey("auto_archive_duration", serializer()) + public object AutoArchiveDuration : + AuditLogChangeKey("auto_archive_duration", ArchiveDuration.serializer()) @SerialName("default_auto_archive_duration") public object DefaultAutoArchiveDuration : - AuditLogChangeKey("default_auto_archive_duration", serializer()) + AuditLogChangeKey("default_auto_archive_duration", ArchiveDuration.serializer()) @SerialName("entity_type") - public object EntityType : AuditLogChangeKey( - "entity_type", - serializer() - ) + public object EntityType : AuditLogChangeKey("entity_type", ScheduledEntityType.serializer()) @SerialName("status") - public object Status : AuditLogChangeKey( - "status", - serializer() - ) + public object Status : + AuditLogChangeKey("status", GuildScheduledEventStatus.serializer()) @SerialName("sku_ids") - public object SkuIds : AuditLogChangeKey>( - "sku_ids", - serializer() - ) + public object SkuIds : AuditLogChangeKey>("sku_ids", ListSerializer(Snowflake.serializer())) internal class Serializer(val type: KSerializer) : KSerializer> { override val descriptor: SerialDescriptor diff --git a/common/src/main/kotlin/entity/AutoModeration.kt b/common/src/commonMain/kotlin/entity/AutoModeration.kt similarity index 100% rename from common/src/main/kotlin/entity/AutoModeration.kt rename to common/src/commonMain/kotlin/entity/AutoModeration.kt diff --git a/common/src/main/kotlin/entity/Data.kt b/common/src/commonMain/kotlin/entity/Data.kt similarity index 100% rename from common/src/main/kotlin/entity/Data.kt rename to common/src/commonMain/kotlin/entity/Data.kt diff --git a/common/src/main/kotlin/entity/DiscordActivity.kt b/common/src/commonMain/kotlin/entity/DiscordActivity.kt similarity index 99% rename from common/src/main/kotlin/entity/DiscordActivity.kt rename to common/src/commonMain/kotlin/entity/DiscordActivity.kt index 9b1fd74dcd43..dd1dd521d966 100644 --- a/common/src/main/kotlin/entity/DiscordActivity.kt +++ b/common/src/commonMain/kotlin/entity/DiscordActivity.kt @@ -13,6 +13,8 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlin.DeprecationLevel.HIDDEN import kotlin.LazyThreadSafetyMode.PUBLICATION +import kotlin.jvm.JvmField +import kotlin.jvm.JvmStatic @Serializable public data class DiscordBotActivity( diff --git a/common/src/main/kotlin/entity/DiscordApplication.kt b/common/src/commonMain/kotlin/entity/DiscordApplication.kt similarity index 99% rename from common/src/main/kotlin/entity/DiscordApplication.kt rename to common/src/commonMain/kotlin/entity/DiscordApplication.kt index 59d8076599ea..64bb61152132 100644 --- a/common/src/main/kotlin/entity/DiscordApplication.kt +++ b/common/src/commonMain/kotlin/entity/DiscordApplication.kt @@ -12,6 +12,7 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmName public sealed interface BaseDiscordApplication { public val id: Snowflake diff --git a/common/src/main/kotlin/entity/DiscordChannel.kt b/common/src/commonMain/kotlin/entity/DiscordChannel.kt similarity index 99% rename from common/src/main/kotlin/entity/DiscordChannel.kt rename to common/src/commonMain/kotlin/entity/DiscordChannel.kt index 8315021d321d..cebfee562112 100644 --- a/common/src/main/kotlin/entity/DiscordChannel.kt +++ b/common/src/commonMain/kotlin/entity/DiscordChannel.kt @@ -99,6 +99,7 @@ import kotlin.DeprecationLevel.HIDDEN import kotlin.LazyThreadSafetyMode.PUBLICATION import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmName import kotlin.time.Duration import kotlin.time.Duration.Companion.minutes diff --git a/common/src/main/kotlin/entity/DiscordComponent.kt b/common/src/commonMain/kotlin/entity/DiscordComponent.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordComponent.kt rename to common/src/commonMain/kotlin/entity/DiscordComponent.kt diff --git a/common/src/main/kotlin/entity/DiscordConnection.kt b/common/src/commonMain/kotlin/entity/DiscordConnection.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordConnection.kt rename to common/src/commonMain/kotlin/entity/DiscordConnection.kt diff --git a/common/src/main/kotlin/entity/DiscordEmoji.kt b/common/src/commonMain/kotlin/entity/DiscordEmoji.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordEmoji.kt rename to common/src/commonMain/kotlin/entity/DiscordEmoji.kt diff --git a/common/src/main/kotlin/entity/DiscordGuild.kt b/common/src/commonMain/kotlin/entity/DiscordGuild.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordGuild.kt rename to common/src/commonMain/kotlin/entity/DiscordGuild.kt diff --git a/common/src/main/kotlin/entity/DiscordGuildOnboarding.kt b/common/src/commonMain/kotlin/entity/DiscordGuildOnboarding.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordGuildOnboarding.kt rename to common/src/commonMain/kotlin/entity/DiscordGuildOnboarding.kt diff --git a/common/src/main/kotlin/entity/DiscordGuildPreview.kt b/common/src/commonMain/kotlin/entity/DiscordGuildPreview.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordGuildPreview.kt rename to common/src/commonMain/kotlin/entity/DiscordGuildPreview.kt diff --git a/common/src/main/kotlin/entity/DiscordGuildScheduledEvent.kt b/common/src/commonMain/kotlin/entity/DiscordGuildScheduledEvent.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordGuildScheduledEvent.kt rename to common/src/commonMain/kotlin/entity/DiscordGuildScheduledEvent.kt diff --git a/common/src/main/kotlin/entity/DiscordGuildWidget.kt b/common/src/commonMain/kotlin/entity/DiscordGuildWidget.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordGuildWidget.kt rename to common/src/commonMain/kotlin/entity/DiscordGuildWidget.kt diff --git a/common/src/main/kotlin/entity/DiscordIntegration.kt b/common/src/commonMain/kotlin/entity/DiscordIntegration.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordIntegration.kt rename to common/src/commonMain/kotlin/entity/DiscordIntegration.kt diff --git a/common/src/main/kotlin/entity/DiscordInvite.kt b/common/src/commonMain/kotlin/entity/DiscordInvite.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordInvite.kt rename to common/src/commonMain/kotlin/entity/DiscordInvite.kt diff --git a/common/src/main/kotlin/entity/DiscordMessage.kt b/common/src/commonMain/kotlin/entity/DiscordMessage.kt similarity index 99% rename from common/src/main/kotlin/entity/DiscordMessage.kt rename to common/src/commonMain/kotlin/entity/DiscordMessage.kt index 37b4904e030e..263a79c080ab 100644 --- a/common/src/main/kotlin/entity/DiscordMessage.kt +++ b/common/src/commonMain/kotlin/entity/DiscordMessage.kt @@ -108,6 +108,7 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmName /** * Represents [a message sent in a channel within Discord](https://discord.com/developers/docs/resources/channel#message-object). diff --git a/common/src/main/kotlin/entity/DiscordNull.kt b/common/src/commonMain/kotlin/entity/DiscordNull.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordNull.kt rename to common/src/commonMain/kotlin/entity/DiscordNull.kt diff --git a/common/src/main/kotlin/entity/DiscordRole.kt b/common/src/commonMain/kotlin/entity/DiscordRole.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordRole.kt rename to common/src/commonMain/kotlin/entity/DiscordRole.kt diff --git a/common/src/main/kotlin/entity/DiscordSelectOption.kt b/common/src/commonMain/kotlin/entity/DiscordSelectOption.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordSelectOption.kt rename to common/src/commonMain/kotlin/entity/DiscordSelectOption.kt diff --git a/common/src/main/kotlin/entity/DiscordShard.kt b/common/src/commonMain/kotlin/entity/DiscordShard.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordShard.kt rename to common/src/commonMain/kotlin/entity/DiscordShard.kt diff --git a/common/src/main/kotlin/entity/DiscordStageInstance.kt b/common/src/commonMain/kotlin/entity/DiscordStageInstance.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordStageInstance.kt rename to common/src/commonMain/kotlin/entity/DiscordStageInstance.kt diff --git a/common/src/main/kotlin/entity/DiscordTemplate.kt b/common/src/commonMain/kotlin/entity/DiscordTemplate.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordTemplate.kt rename to common/src/commonMain/kotlin/entity/DiscordTemplate.kt diff --git a/common/src/main/kotlin/entity/DiscordUser.kt b/common/src/commonMain/kotlin/entity/DiscordUser.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordUser.kt rename to common/src/commonMain/kotlin/entity/DiscordUser.kt diff --git a/common/src/main/kotlin/entity/DiscordWebhook.kt b/common/src/commonMain/kotlin/entity/DiscordWebhook.kt similarity index 100% rename from common/src/main/kotlin/entity/DiscordWebhook.kt rename to common/src/commonMain/kotlin/entity/DiscordWebhook.kt diff --git a/common/src/main/kotlin/entity/Interactions.kt b/common/src/commonMain/kotlin/entity/Interactions.kt similarity index 100% rename from common/src/main/kotlin/entity/Interactions.kt rename to common/src/commonMain/kotlin/entity/Interactions.kt diff --git a/common/src/main/kotlin/entity/Member.kt b/common/src/commonMain/kotlin/entity/Member.kt similarity index 100% rename from common/src/main/kotlin/entity/Member.kt rename to common/src/commonMain/kotlin/entity/Member.kt diff --git a/common/src/main/kotlin/entity/Permission.kt b/common/src/commonMain/kotlin/entity/Permission.kt similarity index 99% rename from common/src/main/kotlin/entity/Permission.kt rename to common/src/commonMain/kotlin/entity/Permission.kt index a5f27c30332d..ce1ed2211562 100644 --- a/common/src/main/kotlin/entity/Permission.kt +++ b/common/src/commonMain/kotlin/entity/Permission.kt @@ -11,6 +11,7 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmName @Serializable(with = Permissions.Companion::class) diff --git a/common/src/main/kotlin/entity/Presence.kt b/common/src/commonMain/kotlin/entity/Presence.kt similarity index 100% rename from common/src/main/kotlin/entity/Presence.kt rename to common/src/commonMain/kotlin/entity/Presence.kt diff --git a/common/src/main/kotlin/entity/Snowflake.kt b/common/src/commonMain/kotlin/entity/Snowflake.kt similarity index 94% rename from common/src/main/kotlin/entity/Snowflake.kt rename to common/src/commonMain/kotlin/entity/Snowflake.kt index ba5a7bffbf47..07a1f2a06ab0 100644 --- a/common/src/main/kotlin/entity/Snowflake.kt +++ b/common/src/commonMain/kotlin/entity/Snowflake.kt @@ -138,7 +138,7 @@ public class Snowflake : Comparable { * * The comparison is based first on the value of the [timestamp], then on the value of the [workerId], then on the * value of the [processId] and finally on the value of the [increment]. It is *consistent with equals*, as defined - * by [Comparable][java.lang.Comparable]. + * by [Comparable](https://docs.oracle.com/javase/8/docs/api/java/lang/Comparable.html). */ override fun compareTo(other: Snowflake): Int { // the layout of Snowflake values from MSB to LSB is timestamp, workerId, processId, increment, @@ -175,9 +175,10 @@ public class Snowflake : Comparable { * [processId] and [increment] are not taken into account. * * Note: this comparator imposes an ordering that is *inconsistent with equals*, as defined by - * [Comparator][java.util.Comparator]. It therefore shouldn't be used to order a - * [SortedSet][java.util.SortedSet] or [SortedMap][java.util.SortedMap]. This is because `TimestampComparator` - * only compares the first 42 bits of the ULong [value] (comparing the timestamp), whereas + * [Comparator](https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html). It therefore shouldn't be + * used to order a [SortedSet](https://docs.oracle.com/javase/8/docs/api/java/util/SortedSet.html) or + * [SortedMap](https://docs.oracle.com/javase/8/docs/api/java/util/SortedMap.html). This is because + * `TimestampComparator` only compares the first 42 bits of the ULong [value] (comparing the timestamp), whereas * [equals][Snowflake.equals] compares all the bits of the [value]. `TimestampComparator` can return `0` even if * [equals][Snowflake.equals] returns `false`, but [equals][Snowflake.equals] only returns `true` if * `TimestampComparator` returns `0`. diff --git a/common/src/main/kotlin/entity/Team.kt b/common/src/commonMain/kotlin/entity/Team.kt similarity index 100% rename from common/src/main/kotlin/entity/Team.kt rename to common/src/commonMain/kotlin/entity/Team.kt diff --git a/common/src/main/kotlin/entity/optional/Optional.kt b/common/src/commonMain/kotlin/entity/optional/Optional.kt similarity index 98% rename from common/src/main/kotlin/entity/optional/Optional.kt rename to common/src/commonMain/kotlin/entity/optional/Optional.kt index c67a8cbebe7d..96b157dfe696 100644 --- a/common/src/main/kotlin/entity/optional/Optional.kt +++ b/common/src/commonMain/kotlin/entity/optional/Optional.kt @@ -9,6 +9,8 @@ import kotlinx.serialization.SerializationException import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import kotlin.js.JsName +import kotlin.jvm.JvmName /** * Represents a value that encapsulates all [three possible states of a value in the Discord API](https://discord.com/developers/docs/reference#nullable-and-optional-resource-fields). @@ -143,6 +145,7 @@ public sealed class Optional { * Returns an [Optional] that is either [value] on a non-null [value], or [Null] on `null`. */ @JvmName("invokeNullable") + @JsName("invokeNullable") public operator fun invoke(value: T?): Optional = when (value) { null -> Null() else -> Value(value) @@ -252,6 +255,7 @@ public inline fun Optional.flatMap(mapper: (E) -> Optional @Suppress("UNCHECKED_CAST") @JvmName("mapNullableOptional") +@JsName("mapNullableOptional") public inline fun Optional.map(mapper: (E) -> T): Optional = when (this) { is Missing, is Null<*> -> this as Optional is Value -> Value(mapper(value!!)) @@ -285,6 +289,7 @@ public inline fun Optional.mapSnowflake(mapper: (E) -> Snowflake): } @JvmName("mapNullableSnowflake") +@JsName("mapNullableSnowflake") public inline fun Optional.mapSnowflake(mapper: (E) -> Snowflake): OptionalSnowflake = when (this) { is Missing, is Null<*> -> OptionalSnowflake.Missing is Value -> OptionalSnowflake.Value(mapper(value!!)) diff --git a/common/src/main/kotlin/entity/optional/OptionalBoolean.kt b/common/src/commonMain/kotlin/entity/optional/OptionalBoolean.kt similarity index 100% rename from common/src/main/kotlin/entity/optional/OptionalBoolean.kt rename to common/src/commonMain/kotlin/entity/optional/OptionalBoolean.kt diff --git a/common/src/main/kotlin/entity/optional/OptionalInt.kt b/common/src/commonMain/kotlin/entity/optional/OptionalInt.kt similarity index 100% rename from common/src/main/kotlin/entity/optional/OptionalInt.kt rename to common/src/commonMain/kotlin/entity/optional/OptionalInt.kt diff --git a/common/src/main/kotlin/entity/optional/OptionalLong.kt b/common/src/commonMain/kotlin/entity/optional/OptionalLong.kt similarity index 100% rename from common/src/main/kotlin/entity/optional/OptionalLong.kt rename to common/src/commonMain/kotlin/entity/optional/OptionalLong.kt diff --git a/common/src/main/kotlin/entity/optional/OptionalSnowflake.kt b/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt similarity index 99% rename from common/src/main/kotlin/entity/optional/OptionalSnowflake.kt rename to common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt index cd304db75048..f8fbbdb9ef9b 100644 --- a/common/src/main/kotlin/entity/optional/OptionalSnowflake.kt +++ b/common/src/commonMain/kotlin/entity/optional/OptionalSnowflake.kt @@ -7,6 +7,7 @@ import kotlinx.serialization.builtins.serializer import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder +import kotlin.jvm.JvmName /** * Represents a value that encapsulate a [Snowflake]'s diff --git a/common/src/main/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt similarity index 98% rename from common/src/main/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt rename to common/src/commonMain/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt index 698e198fa821..dfb602cad61e 100644 --- a/common/src/main/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalBooleanDelegate.kt @@ -3,6 +3,7 @@ package dev.kord.common.entity.optional.delegate import dev.kord.common.entity.optional.OptionalBoolean import dev.kord.common.entity.optional.optional import dev.kord.common.entity.optional.value +import kotlin.jvm.JvmName import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty diff --git a/common/src/main/kotlin/entity/optional/delegate/OptionalDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalDelegate.kt similarity index 95% rename from common/src/main/kotlin/entity/optional/delegate/OptionalDelegate.kt rename to common/src/commonMain/kotlin/entity/optional/delegate/OptionalDelegate.kt index e2b498760f03..cf5f6517d4b7 100644 --- a/common/src/main/kotlin/entity/optional/delegate/OptionalDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalDelegate.kt @@ -1,6 +1,8 @@ package dev.kord.common.entity.optional.delegate import dev.kord.common.entity.optional.Optional +import kotlin.js.JsName +import kotlin.jvm.JvmName import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty @@ -42,6 +44,7 @@ public fun KMutableProperty0>>.delegateList(): ReadWr } @JvmName("provideNullableDelegate") +@JsName("provideNullableDelegate") public fun KMutableProperty0>.delegate(): ReadWriteProperty = object : ReadWriteProperty { diff --git a/common/src/main/kotlin/entity/optional/delegate/OptionalIntDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalIntDelegate.kt similarity index 94% rename from common/src/main/kotlin/entity/optional/delegate/OptionalIntDelegate.kt rename to common/src/commonMain/kotlin/entity/optional/delegate/OptionalIntDelegate.kt index e938aab84a6d..239c8e844109 100644 --- a/common/src/main/kotlin/entity/optional/delegate/OptionalIntDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalIntDelegate.kt @@ -3,10 +3,13 @@ package dev.kord.common.entity.optional.delegate import dev.kord.common.entity.optional.OptionalInt import dev.kord.common.entity.optional.optionalInt import dev.kord.common.entity.optional.value +import kotlin.js.JsName +import kotlin.jvm.JvmName import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty +@JsName("intDelegate") public fun KMutableProperty0.delegate(): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Any?, property: KProperty<*>): Int? { diff --git a/common/src/main/kotlin/entity/optional/delegate/OptionalLongDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalLongDelegate.kt similarity index 98% rename from common/src/main/kotlin/entity/optional/delegate/OptionalLongDelegate.kt rename to common/src/commonMain/kotlin/entity/optional/delegate/OptionalLongDelegate.kt index 1f3e674d5574..8e67e2ecfef3 100644 --- a/common/src/main/kotlin/entity/optional/delegate/OptionalLongDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalLongDelegate.kt @@ -3,6 +3,7 @@ package dev.kord.common.entity.optional.delegate import dev.kord.common.entity.optional.OptionalLong import dev.kord.common.entity.optional.optional import dev.kord.common.entity.optional.value +import kotlin.jvm.JvmName import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty diff --git a/common/src/main/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt similarity index 98% rename from common/src/main/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt rename to common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt index 975f299eb4ec..756689e8972e 100644 --- a/common/src/main/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt +++ b/common/src/commonMain/kotlin/entity/optional/delegate/OptionalSnowflakeDelegate.kt @@ -4,6 +4,7 @@ import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.OptionalSnowflake import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.common.entity.optional.value +import kotlin.jvm.JvmName import kotlin.properties.ReadWriteProperty import kotlin.reflect.KMutableProperty0 import kotlin.reflect.KProperty diff --git a/common/src/main/kotlin/exception/RequestException.kt b/common/src/commonMain/kotlin/exception/RequestException.kt similarity index 100% rename from common/src/main/kotlin/exception/RequestException.kt rename to common/src/commonMain/kotlin/exception/RequestException.kt diff --git a/common/src/commonMain/kotlin/http/HttpEngine.kt b/common/src/commonMain/kotlin/http/HttpEngine.kt new file mode 100644 index 000000000000..feabfdbdebd6 --- /dev/null +++ b/common/src/commonMain/kotlin/http/HttpEngine.kt @@ -0,0 +1,8 @@ +package dev.kord.common.http + +import dev.kord.common.annotation.KordInternal +import io.ktor.client.engine.* + +/** @suppress */ +@KordInternal +public expect object HttpEngine : HttpClientEngineFactory diff --git a/common/src/main/kotlin/ratelimit/AbstractIntervalRateLimiter.kt b/common/src/commonMain/kotlin/ratelimit/AbstractIntervalRateLimiter.kt similarity index 100% rename from common/src/main/kotlin/ratelimit/AbstractIntervalRateLimiter.kt rename to common/src/commonMain/kotlin/ratelimit/AbstractIntervalRateLimiter.kt diff --git a/common/src/main/kotlin/ratelimit/ClockIntervalRateLimiter.kt b/common/src/commonMain/kotlin/ratelimit/ClockIntervalRateLimiter.kt similarity index 100% rename from common/src/main/kotlin/ratelimit/ClockIntervalRateLimiter.kt rename to common/src/commonMain/kotlin/ratelimit/ClockIntervalRateLimiter.kt diff --git a/common/src/main/kotlin/ratelimit/RateLimiter.kt b/common/src/commonMain/kotlin/ratelimit/RateLimiter.kt similarity index 100% rename from common/src/main/kotlin/ratelimit/RateLimiter.kt rename to common/src/commonMain/kotlin/ratelimit/RateLimiter.kt diff --git a/common/src/main/kotlin/ratelimit/TimeSourceIntervalRateLimiter.kt b/common/src/commonMain/kotlin/ratelimit/TimeSourceIntervalRateLimiter.kt similarity index 100% rename from common/src/main/kotlin/ratelimit/TimeSourceIntervalRateLimiter.kt rename to common/src/commonMain/kotlin/ratelimit/TimeSourceIntervalRateLimiter.kt diff --git a/common/src/main/kotlin/serialization/DurationSerializers.kt b/common/src/commonMain/kotlin/serialization/DurationSerializers.kt similarity index 100% rename from common/src/main/kotlin/serialization/DurationSerializers.kt rename to common/src/commonMain/kotlin/serialization/DurationSerializers.kt diff --git a/common/src/main/kotlin/serialization/InstantSerializers.kt b/common/src/commonMain/kotlin/serialization/InstantSerializers.kt similarity index 100% rename from common/src/main/kotlin/serialization/InstantSerializers.kt rename to common/src/commonMain/kotlin/serialization/InstantSerializers.kt diff --git a/common/src/main/kotlin/serialization/LongOrStringSerializer.kt b/common/src/commonMain/kotlin/serialization/LongOrStringSerializer.kt similarity index 100% rename from common/src/main/kotlin/serialization/LongOrStringSerializer.kt rename to common/src/commonMain/kotlin/serialization/LongOrStringSerializer.kt diff --git a/common/src/test/kotlin/BitSetTests.kt b/common/src/commonTest/kotlin/BitSetTests.kt similarity index 84% rename from common/src/test/kotlin/BitSetTests.kt rename to common/src/commonTest/kotlin/BitSetTests.kt index c4fe11871bbf..0360bdfdf600 100644 --- a/common/src/test/kotlin/BitSetTests.kt +++ b/common/src/commonTest/kotlin/BitSetTests.kt @@ -1,9 +1,11 @@ -import dev.kord.common.DiscordBitSet -import dev.kord.common.EmptyBitSet +package dev.kord.common + +import kotlin.js.JsName import kotlin.test.* class BitSetTests { @Test + @JsName("test1") fun `a contains b and c`() { val a = DiscordBitSet(0b111) val b = DiscordBitSet(0b101) @@ -13,6 +15,7 @@ class BitSetTests { } @Test + @JsName("test2") fun `a and b are equal and have the same hashCode`() { val a = DiscordBitSet(0b111, 0) val b = DiscordBitSet(0b111) @@ -21,6 +24,7 @@ class BitSetTests { } @Test + @JsName("test3") fun `a does not equal b`() { val a = DiscordBitSet(0b111, 0) val b = DiscordBitSet(0b111, 0b1) @@ -28,6 +32,7 @@ class BitSetTests { } @Test + @JsName("test4") fun `get bits`() { val a = DiscordBitSet(0b101, 0) assertTrue(a[0]) @@ -41,6 +46,7 @@ class BitSetTests { } @Test + @JsName("test5") fun `set bits`() { val a = EmptyBitSet() for (i in 0..64) a[i] = true @@ -56,28 +62,32 @@ class BitSetTests { } @Test + @JsName("test6") fun `get a bit out of range`() { val a = DiscordBitSet(0b101, 0) - assert(!a[10000]) + assertFalse(a[10000]) } @Test + @JsName("test7") fun `add and remove a bit`() { val a = DiscordBitSet(0b101, 0) a.add(DiscordBitSet(0b111)) - assert(a.value == 0b111.toString()) + assertEquals(0b111.toString(), a.value) a.remove(DiscordBitSet(0b001)) - assert(a.value == 0b110.toString()) + assertEquals(0b110.toString(), a.value) } @Test + @JsName("test8") fun `remove a bit`() { val a = DiscordBitSet(0b101, 0) a.remove(DiscordBitSet(0b111)) - assert(a.value == "0") + assertEquals("0", a.value) } @Test + @JsName("test9") fun `binary works`() { assertEquals("0", DiscordBitSet().binary) assertEquals("0", DiscordBitSet(0).binary) diff --git a/common/src/test/kotlin/ColorTests.kt b/common/src/commonTest/kotlin/ColorTests.kt similarity index 61% rename from common/src/test/kotlin/ColorTests.kt rename to common/src/commonTest/kotlin/ColorTests.kt index bff3b9261913..5dfd63076ae1 100644 --- a/common/src/test/kotlin/ColorTests.kt +++ b/common/src/commonTest/kotlin/ColorTests.kt @@ -1,16 +1,19 @@ -import dev.kord.common.Color -import dev.kord.common.kColor -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows +package dev.kord.common + +import kotlin.js.JsName +import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFailsWith class ColorTests { @Test + @JsName("test1") fun `Color throws if invalid rgb value is provided`() { - assertThrows { Color(256, 256, 300) } + assertFailsWith { Color(256, 256, 300) } } @Test + @JsName("test2") fun `Color provides a correct value`() { val red = Color(0xFF0000) assertEquals(255, red.red) @@ -25,15 +28,7 @@ class ColorTests { } @Test - fun `java to kColor conversion`() { - val color = java.awt.Color.decode("#DBD0B4").kColor - - assertEquals(219, color.red) - assertEquals(208, color.green) - assertEquals(180, color.blue) - } - - @Test + @JsName("test3") fun `Color implementation should drop alpha values if given`() { val color = Color(0x1E1F2E3D) assertEquals(0x1F2E3D, color.rgb) diff --git a/common/src/test/kotlin/FixedClock.kt b/common/src/commonTest/kotlin/FixedClock.kt similarity index 90% rename from common/src/test/kotlin/FixedClock.kt rename to common/src/commonTest/kotlin/FixedClock.kt index 9268573652a9..b34fdb8dcf78 100644 --- a/common/src/test/kotlin/FixedClock.kt +++ b/common/src/commonTest/kotlin/FixedClock.kt @@ -1,3 +1,5 @@ +package dev.kord.common + import kotlinx.datetime.Clock import kotlinx.datetime.Instant diff --git a/common/src/test/kotlin/LocaleTest.kt b/common/src/commonTest/kotlin/LocaleTest.kt similarity index 95% rename from common/src/test/kotlin/LocaleTest.kt rename to common/src/commonTest/kotlin/LocaleTest.kt index e8f29c8b4ba3..3130f7f8516a 100644 --- a/common/src/test/kotlin/LocaleTest.kt +++ b/common/src/commonTest/kotlin/LocaleTest.kt @@ -1,7 +1,9 @@ -import dev.kord.common.Locale +package dev.kord.common + import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals @@ -49,6 +51,7 @@ class LocaleTest { @Test + @JsName("test1") fun `all documented Locales can be deserialized`() { all.forEach { (string, locale) -> assertEquals(expected = locale, actual = Json.decodeFromString("\"$string\"")) @@ -56,6 +59,7 @@ class LocaleTest { } @Test + @JsName("test2") fun `all documented Locales can be serialized`() { all.forEach { (string, locale) -> assertEquals(expected = "\"$string\"", actual = Json.encodeToString(locale)) diff --git a/common/src/test/kotlin/entity/SnowflakeTest.kt b/common/src/commonTest/kotlin/entity/SnowflakeTest.kt similarity index 91% rename from common/src/test/kotlin/entity/SnowflakeTest.kt rename to common/src/commonTest/kotlin/entity/SnowflakeTest.kt index 23832a7985a4..6a52cfdc51af 100644 --- a/common/src/test/kotlin/entity/SnowflakeTest.kt +++ b/common/src/commonTest/kotlin/entity/SnowflakeTest.kt @@ -1,8 +1,8 @@ -package entity +package dev.kord.common.entity -import dev.kord.common.entity.Snowflake import kotlinx.datetime.Clock import kotlinx.datetime.Instant +import kotlin.js.JsName import kotlin.test.* import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.nanoseconds @@ -10,46 +10,54 @@ import kotlin.time.Duration.Companion.nanoseconds class SnowflakeTest { @Test + @JsName("test1") fun `min Snowflake's timestamp is equal to discordEpoch`() { assertEquals(Snowflake.discordEpoch, Snowflake.min.timestamp) } @Test + @JsName("test2") fun `max Snowflake's timestamp is equal to endOfTime`() { assertEquals(Snowflake.endOfTime, Snowflake.max.timestamp) } @Test + @JsName("test3") fun `Snowflake created from ULong MIN_VALUE has timestamp equal to discordEpoch`() { val snowflake = Snowflake(ULong.MIN_VALUE) assertEquals(Snowflake.discordEpoch, snowflake.timestamp) } @Test + @JsName("test4") fun `Snowflake created from ULong MAX_VALUE has timestamp equal to endOfTime`() { val snowflake = Snowflake(ULong.MAX_VALUE) assertEquals(Snowflake.endOfTime, snowflake.timestamp) } @Test + @JsName("test5") fun `Snowflake created from Long MIN_VALUE has timestamp equal to discordEpoch`() { val snowflake = Snowflake(Long.MIN_VALUE) assertEquals(Snowflake.discordEpoch, snowflake.timestamp) } @Test + @JsName("test6") fun `Snowflake created from instant far in the past has timestamp equal to discordEpoch`() { val snowflake = Snowflake(Instant.DISTANT_PAST) assertEquals(Snowflake.discordEpoch, snowflake.timestamp) } @Test + @JsName("test7") fun `Snowflake created from instant far in the future has timestamp equal to endOfTime`() { val snowflake = Snowflake(Instant.DISTANT_FUTURE) assertEquals(Snowflake.endOfTime, snowflake.timestamp) } @Test + @JsName("test8") fun `Snowflake's timestamp calculates an Instant close to the Instant the Snowflake was created from`() { val instant = Clock.System.now() val snowflake = Snowflake(instant) @@ -62,16 +70,19 @@ class SnowflakeTest { } @Test + @JsName("test9") fun `min Snowflake's timeMark has passed`() { assertTrue(Snowflake.min.timeMark.hasPassedNow()) } @Test + @JsName("test10") fun `max Snowflake's timeMark has not passed`() { assertFalse(Snowflake.max.timeMark.hasPassedNow()) } @Test + @JsName("test11") fun `Snowflake can be destructured`() { val snowflake = Snowflake(0b110010110111_10111_01101_101100111101_u) val (timestamp, worker, process, increment) = snowflake @@ -88,6 +99,7 @@ class SnowflakeTest { } @Test + @JsName("test12") fun `Snowflakes are compared correctly`() { // timestamp worker process increment // vvv vvv vvv vvv @@ -116,13 +128,4 @@ class SnowflakeTest { assertEquals(0, compare(c, f)) } } - - @Test - fun `Snowflake's natural order works with SortedSets`() { - val a = Snowflake(0b0_00000_00000_000000000000_u) - val b = Snowflake(0b0_00000_00000_000000000001_u) - val c = Snowflake(0b1_00000_00000_000000000000_u) - assertEquals(2, sortedSetOf(a, b).size) - assertEquals(2, sortedSetOf(a, c).size) - } } diff --git a/common/src/test/kotlin/entity/optional/OptionalBooleanTest.kt b/common/src/commonTest/kotlin/entity/optional/OptionalBooleanTest.kt similarity index 71% rename from common/src/test/kotlin/entity/optional/OptionalBooleanTest.kt rename to common/src/commonTest/kotlin/entity/optional/OptionalBooleanTest.kt index 14b32bf1d2b6..74142b875b27 100644 --- a/common/src/test/kotlin/entity/optional/OptionalBooleanTest.kt +++ b/common/src/commonTest/kotlin/entity/optional/OptionalBooleanTest.kt @@ -4,9 +4,11 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertFailsWith +import kotlin.test.assertIs +import kotlin.test.assertTrue internal class OptionalBooleanTest { @@ -14,24 +16,26 @@ internal class OptionalBooleanTest { private class EmptyOptionalEntity(val value: OptionalBoolean = OptionalBoolean.Missing) @Test + @JsName("test1") fun `deserializing nothing in optional assigns Missing`(){ - @Language("json") + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is OptionalBoolean.Missing) + assertIs(entity.value) } @Serializable private class NullOptionalEntity(@Suppress("unused") val value: OptionalBoolean = OptionalBoolean.Missing) @Test + @JsName("test2") fun `deserializing null in optional throws SerializationException`(){ - @Language("json") + //language=json val json = """{ "value":null }""" - org.junit.jupiter.api.assertThrows { + assertFailsWith { Json.decodeFromString(json) } } @@ -40,15 +44,16 @@ internal class OptionalBooleanTest { private class ValueOptionalEntity(@Suppress("unused") val value: OptionalBoolean = OptionalBoolean.Missing) @Test + @JsName("test3") fun `deserializing value in optional assigns Value`(){ - @Language("json") + //language=json val json = """{ "value":true }""" val entity = Json.decodeFromString(json) - require(entity.value is OptionalBoolean.Value) + assertIs(entity.value) - Assertions.assertEquals(true, entity.value.value) + assertTrue(entity.value.value) } } diff --git a/common/src/test/kotlin/entity/optional/OptionalIntTest.kt b/common/src/commonTest/kotlin/entity/optional/OptionalIntTest.kt similarity index 73% rename from common/src/test/kotlin/entity/optional/OptionalIntTest.kt rename to common/src/commonTest/kotlin/entity/optional/OptionalIntTest.kt index a6f497e26be5..cda9d356eb19 100644 --- a/common/src/test/kotlin/entity/optional/OptionalIntTest.kt +++ b/common/src/commonTest/kotlin/entity/optional/OptionalIntTest.kt @@ -4,9 +4,8 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.* internal class OptionalIntTest { @@ -14,13 +13,14 @@ internal class OptionalIntTest { private class EmptyOptionalEntity(val value: OptionalInt = OptionalInt.Missing) @Test + @JsName("test1") fun `deserializing nothing in optional assigns Missing`(){ - @Language("json") + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is OptionalInt.Missing) + assertIs(entity.value) } @@ -28,12 +28,13 @@ internal class OptionalIntTest { private class NullOptionalEntity(@Suppress("unused") val value: OptionalInt = OptionalInt.Missing) @Test + @JsName("test2") fun `deserializing null in optional throws SerializationException`(){ - @Language("json") + //language=json val json = """{ "value":null }""" - org.junit.jupiter.api.assertThrows { + assertFailsWith { Json.decodeFromString(json) } } @@ -42,14 +43,15 @@ internal class OptionalIntTest { class ValueOptionalEntity(@Suppress("unused") val value: OptionalInt = OptionalInt.Missing) @Test + @JsName("test3") fun `deserializing value in optional assigns Value`(){ - @Language("json") + //language=json val json = """{ "value":5 }""" val entity = Json.decodeFromString(json) - require(entity.value is OptionalInt.Value) + assertIs(entity.value) - assertEquals(5, entity.value.value) + assertSame(5, entity.value.value) } } diff --git a/common/src/test/kotlin/entity/optional/OptionalLongTest.kt b/common/src/commonTest/kotlin/entity/optional/OptionalLongTest.kt similarity index 73% rename from common/src/test/kotlin/entity/optional/OptionalLongTest.kt rename to common/src/commonTest/kotlin/entity/optional/OptionalLongTest.kt index 9ec0618be62b..d67d1e6d5d53 100644 --- a/common/src/test/kotlin/entity/optional/OptionalLongTest.kt +++ b/common/src/commonTest/kotlin/entity/optional/OptionalLongTest.kt @@ -4,9 +4,8 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.* internal class OptionalLongTest { @@ -14,14 +13,15 @@ internal class OptionalLongTest { class EmptyOptionalEntity(val value: OptionalLong = OptionalLong.Missing) @Test + @JsName("test1") fun `deserializing nothing in optional assigns Missing`() { - @Language("json") + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is OptionalLong.Missing) + assertIs(entity.value) } @@ -29,12 +29,13 @@ internal class OptionalLongTest { class NullOptionalEntity(@Suppress("unused") val value: OptionalLong = OptionalLong.Missing) @Test + @JsName("test2") fun `deserializing null in optional throws SerializationException`() { - @Language("json") + //language=json val json = """{ "value":null }""" - org.junit.jupiter.api.assertThrows { + assertFailsWith { Json.decodeFromString(json) } } @@ -44,14 +45,15 @@ internal class OptionalLongTest { class ValueOptionalEntity(@Suppress("unused") val value: OptionalLong = OptionalLong.Missing) @Test + @JsName("test3") fun `deserializing value in optional assigns Value`() { - @Language("json") + //language=json val json = """{ "value":5 }""" val entity = Json.decodeFromString(json) - require(entity.value is OptionalLong.Value) + assertIs(entity.value) - Assertions.assertEquals(5, entity.value.value) + assertEquals(5, entity.value.value) } } diff --git a/common/src/test/kotlin/entity/optional/OptionalSnowflakeTest.kt b/common/src/commonTest/kotlin/entity/optional/OptionalSnowflakeTest.kt similarity index 65% rename from common/src/test/kotlin/entity/optional/OptionalSnowflakeTest.kt rename to common/src/commonTest/kotlin/entity/optional/OptionalSnowflakeTest.kt index 3bdc8cb69fa2..d7f4b05a391a 100644 --- a/common/src/test/kotlin/entity/optional/OptionalSnowflakeTest.kt +++ b/common/src/commonTest/kotlin/entity/optional/OptionalSnowflakeTest.kt @@ -5,9 +5,8 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.* internal class OptionalSnowflakeTest { @@ -16,14 +15,15 @@ internal class OptionalSnowflakeTest { class EmptyOptionalEntity(val value: OptionalSnowflake = OptionalSnowflake.Missing) @Test - fun `deserializing nothing in optional assigns Missing`(){ - @Language("json") + @JsName("test1") + fun `deserializing nothing in optional assigns Missing`() { + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is OptionalSnowflake.Missing) + assertIs(entity.value) } @@ -31,11 +31,12 @@ internal class OptionalSnowflakeTest { class NullOptionalEntity(@Suppress("unused") val value: OptionalSnowflake = OptionalSnowflake.Missing) @Test - fun `deserializing null in optional throws SerializationException`(){ - @Language("json") + @JsName("test2") + fun `deserializing null in optional throws SerializationException`() { + //language=json val json = """{ "value":null }""" - org.junit.jupiter.api.assertThrows { + assertFailsWith { Json.decodeFromString(json) } } @@ -45,14 +46,14 @@ internal class OptionalSnowflakeTest { class ValueOptionalEntity(@Suppress("unused") val value: OptionalSnowflake = OptionalSnowflake.Missing) @Test - fun `deserializing value in optional assigns Value`(){ - @Language("json") + @JsName("test3") + fun `deserializing value in optional assigns Value`() { + //language=test val json = """{ "value":5 }""" val entity = Json.decodeFromString(json) - require(entity.value is OptionalSnowflake.Value) - - Assertions.assertEquals(Snowflake(5u), entity.value.value) + assertIs(entity.value) + assertEquals(Snowflake(5u), entity.value.value) } } diff --git a/common/src/test/kotlin/entity/optional/OptionalTest.kt b/common/src/commonTest/kotlin/entity/optional/OptionalTest.kt similarity index 71% rename from common/src/test/kotlin/entity/optional/OptionalTest.kt rename to common/src/commonTest/kotlin/entity/optional/OptionalTest.kt index c06c47e4ae37..25879bfaff6d 100644 --- a/common/src/test/kotlin/entity/optional/OptionalTest.kt +++ b/common/src/commonTest/kotlin/entity/optional/OptionalTest.kt @@ -4,26 +4,31 @@ import kotlinx.serialization.Serializable import kotlinx.serialization.SerializationException import kotlinx.serialization.decodeFromString import kotlinx.serialization.json.Json -import org.intellij.lang.annotations.Language -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFailsWith +import kotlin.test.assertIs internal class OptionalTest { @Test + @JsName("test1") fun `creating optional from nullable value returns Value on non-null value`() { - val value: Int? = 5 + val value = 5 val optional = Optional(value) - assert(optional is Optional.Value) - assert((optional as Optional.Value).value == value) + assertIs>(optional) + assertEquals(optional.value, value) } @Test + @JsName("test2") fun `creating optional from nullable value returns Null on null value`() { val value: Int? = null val optional = Optional(value) - assert(optional is Optional.Null) + assertIs>(optional) } @@ -31,13 +36,14 @@ internal class OptionalTest { private class NullOptionalEntity(val value: Optional = Optional.Missing()) @Test + @JsName("test3") fun `deserializing null in nullable optional assigns Null`() { - @Language("json") + //language=json val json = """{ "value":null }""" val entity = Json.decodeFromString(json) - assert(entity.value is Optional.Null) + assertIs>(entity.value) } @@ -45,13 +51,14 @@ internal class OptionalTest { class EmptyOptionalEntity(val value: Optional = Optional.Missing()) @Test + @JsName("test4") fun `deserializing nothing in nullable optional assigns Missing`() { - @Language("json") + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is Optional.Missing) + assertIs>(entity.value) } @@ -59,13 +66,14 @@ internal class OptionalTest { class UnexpectedEmptyOptionalEntity(val value: Optional = Optional.Missing()) @Test + @JsName("test5") fun `deserializing nothing in non-nullable optional assigns Missing`() { - @Language("json") + //language=json val json = """{}""" val entity = Json.decodeFromString(json) - assert(entity.value is Optional.Missing) + assertIs>(entity.value) } @@ -73,11 +81,12 @@ internal class OptionalTest { private class UnexpectedNullOptionalEntity(@Suppress("unused") val value: Optional = Optional.Missing()) @Test + @JsName("test6") fun `deserializing null in non-nullable optional throws SerializationException`() { - @Language("json") + //language=json val json = """{ "value":null }""" - org.junit.jupiter.api.assertThrows { + assertFailsWith { Json.decodeFromString(json) } } diff --git a/common/src/commonTest/kotlin/file.kt b/common/src/commonTest/kotlin/file.kt new file mode 100644 index 000000000000..7f0b71174f99 --- /dev/null +++ b/common/src/commonTest/kotlin/file.kt @@ -0,0 +1,5 @@ +package dev.kord.common + +import dev.kord.test.file +suspend fun readFile(prefix: String, name: String): String = + file("common", "json/$prefix/$name.json") diff --git a/common/src/test/kotlin/json/ChannelTest.kt b/common/src/commonTest/kotlin/json/ChannelTest.kt similarity index 87% rename from common/src/test/kotlin/json/ChannelTest.kt rename to common/src/commonTest/kotlin/json/ChannelTest.kt index 9b87b0d9619b..9153fbd5d252 100644 --- a/common/src/test/kotlin/json/ChannelTest.kt +++ b/common/src/commonTest/kotlin/json/ChannelTest.kt @@ -1,20 +1,21 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.DiscordChannel import dev.kord.common.entity.optional.value +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName import kotlin.time.Duration.Companion.seconds +import kotlin.test.Test -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/channel/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("channel", name) class ChannelTest { @Test - fun `DMChannel serialization`() { + @JsName("test1") + fun `DMChannel serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("dmchannel")) with(channel) { @@ -34,7 +35,8 @@ class ChannelTest { @Test - fun `ChannelCategory serialization`() { + @JsName("test2") + fun `ChannelCategory serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("channelcategory")) with(channel) { @@ -50,7 +52,8 @@ class ChannelTest { @Test - fun `GroupDMChannel serialization`() { + @JsName("test3") + fun `GroupDMChannel serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("groupdmchannel")) with(channel) { @@ -78,7 +81,8 @@ class ChannelTest { @Test - fun `GuildNewChannel serialization`() { + @JsName("test4") + fun `GuildNewChannel serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("guildnewschannel")) with(channel) { @@ -97,7 +101,8 @@ class ChannelTest { @Test - fun `GuildTextChannel serialization`() { + @JsName("test5") + fun `GuildTextChannel serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("guildtextchannel")) with(channel) { @@ -117,7 +122,8 @@ class ChannelTest { @Test - fun `GuildVoiceChannel serialization`() { + @JsName("test6") + fun `GuildVoiceChannel serialization`() = runTest { val channel = Json.decodeFromString(DiscordChannel.serializer(), file("guildvoicechannel")) with(channel) { diff --git a/common/src/test/kotlin/json/EmojiTest.kt b/common/src/commonTest/kotlin/json/EmojiTest.kt similarity index 74% rename from common/src/test/kotlin/json/EmojiTest.kt rename to common/src/commonTest/kotlin/json/EmojiTest.kt index 528b834932e2..3cca7f47aaf2 100644 --- a/common/src/test/kotlin/json/EmojiTest.kt +++ b/common/src/commonTest/kotlin/json/EmojiTest.kt @@ -1,20 +1,20 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.DiscordEmoji import dev.kord.common.entity.Snowflake +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test - -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/emoji/$name.json").readText() -} +private suspend fun file(name: String): String = readFile("emoji", name) class EmojiTest { @Test - fun `Custom Emoji serialization`() { + @JsName("test1") + fun `Custom Emoji serialization`() = runTest { val emoji = Json.decodeFromString(DiscordEmoji.serializer(), file("customemoji")) with(emoji) { @@ -24,7 +24,8 @@ class EmojiTest { } @Test - fun `Standard Emoji serialization`() { + @JsName("test2") + fun `Standard Emoji serialization`() = runTest { val emoji = Json.decodeFromString(DiscordEmoji.serializer(), file("standardemoji")) with(emoji) { @@ -34,7 +35,8 @@ class EmojiTest { } @Test - fun `Emoji serialization`() { + @JsName("test3") + fun `Emoji serialization`() = runTest { val emoji = Json.decodeFromString(DiscordEmoji.serializer(), file("emoji")) with(emoji) { diff --git a/common/src/test/kotlin/json/GuildTest.kt b/common/src/commonTest/kotlin/json/GuildTest.kt similarity index 87% rename from common/src/test/kotlin/json/GuildTest.kt rename to common/src/commonTest/kotlin/json/GuildTest.kt index a0570b56da2f..d74d43977f83 100644 --- a/common/src/test/kotlin/json/GuildTest.kt +++ b/common/src/commonTest/kotlin/json/GuildTest.kt @@ -1,21 +1,21 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.* +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName import kotlin.time.Duration.Companion.seconds +import kotlin.test.Test - -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/guild/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("guild", name) class GuildTest { @Test - fun `Guild serialization`() { + @JsName("test1") + fun `Guild serialization`() = runTest { val guild = Json.decodeFromString(DiscordGuild.serializer(), file("guild")) with(guild) { @@ -65,7 +65,8 @@ class GuildTest { } @Test - fun `UnavailableGuild serialization`() { + @JsName("test2") + fun `UnavailableGuild serialization`() = runTest { val guild = Json.decodeFromString(DiscordUnavailableGuild.serializer(), file("unavailableguild")) with(guild) { @@ -76,7 +77,8 @@ class GuildTest { } @Test - fun `GuildMember serialization`() { + @JsName("test3") + fun `GuildMember serialization`() = runTest { val member = Json.decodeFromString(DiscordGuildMember.serializer(), file("guildmember")) with(member) { @@ -90,7 +92,8 @@ class GuildTest { } @Test - fun `PartialGuild serialization`() { + @JsName("test4") + fun `PartialGuild serialization`() = runTest { val guild = Json.decodeFromString(DiscordPartialGuild.serializer(), file("partialguild")) with(guild) { diff --git a/common/src/test/kotlin/json/InteractionTest.kt b/common/src/commonTest/kotlin/json/InteractionTest.kt similarity index 83% rename from common/src/test/kotlin/json/InteractionTest.kt rename to common/src/commonTest/kotlin/json/InteractionTest.kt index c962e75d18ac..1f27899a6646 100644 --- a/common/src/test/kotlin/json/InteractionTest.kt +++ b/common/src/commonTest/kotlin/json/InteractionTest.kt @@ -1,14 +1,15 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.* import dev.kord.common.entity.optional.orEmpty +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertIs -private fun file(name: String): String { - val loader = InteractionTest::class.java.classLoader - return loader.getResource("json/interaction/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("interaction", name) class InteractionTest { @@ -17,7 +18,8 @@ class InteractionTest { } @Test - fun `group command can be deserialized`() { + @JsName("test1") + fun `group command can be deserialized`() = runTest { val text = file("groupsubcommand") val interaction = json.decodeFromString(DiscordInteraction.serializer(), text) @@ -31,8 +33,7 @@ class InteractionTest { data.name shouldBe "testsubcommands" data.id shouldBe "792107855418490901" val group = data.options.orEmpty().first() - assert(group is CommandGroup) - group as CommandGroup + assertIs(group) group.name shouldBe "group" val subCommand = group.options.orEmpty().first() subCommand.name shouldBe "groupsubcommand" @@ -45,7 +46,8 @@ class InteractionTest { } @Test - fun `subcommand can be deserialized`() { + @JsName("test2") + fun `subcommand can be deserialized`() = runTest { val text = file("subcommand") val interaction = json.decodeFromString(DiscordInteraction.serializer(), text) @@ -59,8 +61,7 @@ class InteractionTest { data.name shouldBe "testsubcommands" data.id shouldBe "792107855418490901" val subCommand = data.options.orEmpty().first() - assert(subCommand is SubCommand) - subCommand as SubCommand + assertIs(subCommand) subCommand.name shouldBe "subcommand" val arg = subCommand.options.orEmpty().first() arg.type shouldBe ApplicationCommandOptionType.Integer @@ -72,7 +73,8 @@ class InteractionTest { @Test - fun `root can be deserialized`() { + @JsName("test3") + fun `root can be deserialized`() = runTest { val text = file("rootcommand") val interaction = json.decodeFromString(DiscordInteraction.serializer(), text) @@ -86,8 +88,7 @@ class InteractionTest { data.name shouldBe "testsubcommands" data.id shouldBe "792107855418490901" val arg = data.options.orEmpty().first() - assert(arg is CommandArgument<*>) - arg as CommandArgument<*> + assertIs>(arg) arg.type shouldBe ApplicationCommandOptionType.Integer arg.name shouldBe "testint" arg.value shouldBe 1L @@ -96,7 +97,8 @@ class InteractionTest { } @Test - fun `slash command permissions can be serialized`() { + @JsName("test4") + fun `slash command permissions can be serialized`() = runTest { val text = file("slash_command_permissions_update") val interaction = json.decodeFromString(DiscordGuildApplicationCommandPermissions.serializer(), text) @@ -115,14 +117,15 @@ class InteractionTest { } @Test - fun `select menu can be deserialized`() { + @JsName("test5") + fun `select menu can be deserialized`() = runTest { val text = file("selectmenu") val interaction = json.decodeFromString(DiscordInteraction.serializer(), text) with(interaction) { applicationId shouldBe "845027738276462632" channelId shouldBe "772908445358620702" - with(data){ + with(data) { componentType shouldBe ComponentType.StringSelect customId shouldBe "class_select_1" values shouldBe listOf("mage", "rogue") diff --git a/common/src/test/kotlin/json/MessageTest.kt b/common/src/commonTest/kotlin/json/MessageTest.kt similarity index 89% rename from common/src/test/kotlin/json/MessageTest.kt rename to common/src/commonTest/kotlin/json/MessageTest.kt index 5f6bfabd3d13..5fea99400e97 100644 --- a/common/src/test/kotlin/json/MessageTest.kt +++ b/common/src/commonTest/kotlin/json/MessageTest.kt @@ -1,20 +1,20 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.* +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test - -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/message/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("message", name) class MessageTest { @Test - fun `Message serialization`() { + @JsName("test1") + fun `Message serialization`() = runTest { val message: DiscordMessage = Json.decodeFromString(DiscordMessage.serializer(), file("message")) with(message) { @@ -51,7 +51,8 @@ class MessageTest { } @Test - fun `User serialization`() { + @JsName("test2") + fun `User serialization`() = runTest { val message = Json.decodeFromString(DiscordMessage.serializer(), file("crossposted")) with(message) { diff --git a/common/src/test/kotlin/json/PermissionsTest.kt b/common/src/commonTest/kotlin/json/PermissionsTest.kt similarity index 80% rename from common/src/test/kotlin/json/PermissionsTest.kt rename to common/src/commonTest/kotlin/json/PermissionsTest.kt index 63a7c8405d3b..e1dc29845dc1 100644 --- a/common/src/test/kotlin/json/PermissionsTest.kt +++ b/common/src/commonTest/kotlin/json/PermissionsTest.kt @@ -1,16 +1,18 @@ -package json +package dev.kord.common.json import dev.kord.common.DiscordBitSet -import dev.kord.common.EmptyBitSet import dev.kord.common.entity.* import kotlinx.serialization.json.Json import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.put -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals class PermissionsTest { @Test + @JsName("test1") fun `adding permissions together does not swallow the universe`() { Permission.values.fold(Permissions(DiscordBitSet(0))) { acc, permission -> acc + permission @@ -18,11 +20,13 @@ class PermissionsTest { } @Test + @JsName("test2") fun `Permission All does not swallow the universe`() { Permission.All //oh yeah, this is worthy of a test } @Test + @JsName("test3") fun `permissions serialization test`() { val expected = buildJsonObject { put("id", "12323232") @@ -35,10 +39,11 @@ class PermissionsTest { put("mentionable", false) } val actual = Json.decodeFromJsonElement(DiscordRole.serializer(), expected) - assert(actual.permissions.code.value == "123456789876543000000000000") { + assertEquals( + "123456789876543000000000000", actual.permissions.code.value, "1234567898765430000000000 was expected but ${actual.permissions.code.value} was found" - } + ) } -} \ No newline at end of file +} diff --git a/common/src/test/kotlin/json/UserTest.kt b/common/src/commonTest/kotlin/json/UserTest.kt similarity index 70% rename from common/src/test/kotlin/json/UserTest.kt rename to common/src/commonTest/kotlin/json/UserTest.kt index f25a129cc107..a5c9c3e2d821 100644 --- a/common/src/test/kotlin/json/UserTest.kt +++ b/common/src/commonTest/kotlin/json/UserTest.kt @@ -1,19 +1,20 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.DiscordUser import dev.kord.common.entity.UserFlags +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/user/$name.json").readText() -} +private suspend fun file(name: String): String = readFile("user", name) class UserTest { @Test - fun `User serialization`() { + @JsName("test1") + fun `User serialization`() = runTest{ val user = Json.decodeFromString(DiscordUser.serializer(), file("user")) with(user) { diff --git a/common/src/test/kotlin/json/Util.kt b/common/src/commonTest/kotlin/json/Util.kt similarity index 56% rename from common/src/test/kotlin/json/Util.kt rename to common/src/commonTest/kotlin/json/Util.kt index 8f952f310b82..00d62b3c2aa8 100644 --- a/common/src/test/kotlin/json/Util.kt +++ b/common/src/commonTest/kotlin/json/Util.kt @@ -1,69 +1,69 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.* import dev.kord.common.entity.optional.* -import org.junit.jupiter.api.Assertions +import kotlin.test.assertEquals infix fun String?.shouldBe(value: String?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun Optional.shouldBe(value: String?){ - Assertions.assertEquals(value, this.value) + assertEquals(value, this.value) } infix fun OptionalBoolean.shouldBe(value: Boolean){ - Assertions.assertEquals(value, this.value) + assertEquals(value, this.value) } infix fun Snowflake?.shouldBe(value: String?){ - Assertions.assertEquals(value, this?.toString()) + assertEquals(value, this?.toString()) } infix fun OptionalSnowflake?.shouldBe(value: String?){ - Assertions.assertEquals(value, this?.value?.toString()) + assertEquals(value, this?.value?.toString()) } infix fun VerificationLevel?.shouldBe(value: VerificationLevel?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun DefaultMessageNotificationLevel?.shouldBe(value: DefaultMessageNotificationLevel?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun MFALevel?.shouldBe(value: MFALevel?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun ExplicitContentFilter?.shouldBe(value: ExplicitContentFilter?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun PremiumTier?.shouldBe(value: PremiumTier?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun SystemChannelFlags?.shouldBe(value: SystemChannelFlags?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun List?.shouldBe(value: List?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun Int?.shouldBe(value: Int?){ - Assertions.assertEquals(value, this) + assertEquals(value, this) } infix fun OptionalInt?.shouldBe(value: Int?){ - Assertions.assertEquals(value, this.value) + assertEquals(value, this.value) } infix fun Optional.shouldBe(that: T?) { - Assertions.assertEquals(that, this.value) + assertEquals(that, this.value) } infix fun T.shouldBe(that: T) { - Assertions.assertEquals(that, this) + assertEquals(that, this) } diff --git a/common/src/test/kotlin/json/VoiceStateTest.kt b/common/src/commonTest/kotlin/json/VoiceStateTest.kt similarity index 72% rename from common/src/test/kotlin/json/VoiceStateTest.kt rename to common/src/commonTest/kotlin/json/VoiceStateTest.kt index 0aa78e4062b8..1d73de02faf5 100644 --- a/common/src/test/kotlin/json/VoiceStateTest.kt +++ b/common/src/commonTest/kotlin/json/VoiceStateTest.kt @@ -1,19 +1,20 @@ -package json +package dev.kord.common.json import dev.kord.common.entity.DiscordVoiceState +import dev.kord.common.readFile +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test -private fun file(name: String): String { - val loader = ChannelTest::class.java.classLoader - return loader.getResource("json/voice/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("voice", name) class VoiceStateTest { @Test - fun `VoiceState serialization`() { + @JsName("test1") + fun `VoiceState serialization`() = runTest { val state = Json.decodeFromString(DiscordVoiceState.serializer(), file("voicestate")) with(state) { diff --git a/common/src/test/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt b/common/src/commonTest/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt similarity index 94% rename from common/src/test/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt rename to common/src/commonTest/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt index 5abebfbbb03c..2a47a2cf7324 100644 --- a/common/src/test/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt +++ b/common/src/commonTest/kotlin/ratelimit/AbstractIntervalRateLimiterTest.kt @@ -1,8 +1,8 @@ -package ratelimit +package dev.kord.common.ratelimit -import dev.kord.common.ratelimit.IntervalRateLimiter import kotlinx.coroutines.test.currentTime import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest import kotlin.test.Test import kotlin.test.assertEquals @@ -27,6 +27,7 @@ abstract class AbstractIntervalRateLimiterTest { } @Test + @JsName("test1") fun `an interval rate limiter does not accept illegal arguments`() { fun assertIAE(limit: Int, interval: Duration) { @@ -41,6 +42,7 @@ abstract class AbstractIntervalRateLimiterTest { } @Test + @JsName("test2") fun `an interval rate limiter does not ratelimit when under limit`() = runTest { repeat(limit) { rateLimiter.consume() } @@ -48,6 +50,7 @@ abstract class AbstractIntervalRateLimiterTest { } @Test + @JsName("test3") fun `an interval rate limiter does ratelimit when over limit`() = runTest { repeat(limit + 1) { rateLimiter.consume() } diff --git a/common/src/test/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt b/common/src/commonTest/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt similarity index 70% rename from common/src/test/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt rename to common/src/commonTest/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt index c6a3533ca10e..f88681bc4f13 100644 --- a/common/src/test/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt +++ b/common/src/commonTest/kotlin/ratelimit/ClockIntervalRateLimiterTest.kt @@ -1,8 +1,6 @@ -package ratelimit +package dev.kord.common.ratelimit -import dev.kord.common.ratelimit.ClockIntervalRateLimiter -import dev.kord.common.ratelimit.IntervalRateLimiter -import fixed +import dev.kord.common.fixed import kotlinx.datetime.Clock import kotlin.time.Duration diff --git a/common/src/test/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt b/common/src/commonTest/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt similarity index 72% rename from common/src/test/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt rename to common/src/commonTest/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt index 694196d78a6c..2f519e8d2100 100644 --- a/common/src/test/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt +++ b/common/src/commonTest/kotlin/ratelimit/TimeSourceIntervalRateLimiterTest.kt @@ -1,7 +1,5 @@ -package ratelimit +package dev.kord.common.ratelimit -import dev.kord.common.ratelimit.IntervalRateLimiter -import dev.kord.common.ratelimit.TimeSourceIntervalRateLimiter import kotlin.time.Duration import kotlin.time.TestTimeSource diff --git a/common/src/test/kotlin/serialization/DurationSerializersTests.kt b/common/src/commonTest/kotlin/serialization/DurationSerializersTests.kt similarity index 94% rename from common/src/test/kotlin/serialization/DurationSerializersTests.kt rename to common/src/commonTest/kotlin/serialization/DurationSerializersTests.kt index be071f4a8dbb..5a5e5761bdbc 100644 --- a/common/src/test/kotlin/serialization/DurationSerializersTests.kt +++ b/common/src/commonTest/kotlin/serialization/DurationSerializersTests.kt @@ -1,8 +1,8 @@ -package serialization +package dev.kord.common.serialization -import dev.kord.common.serialization.* import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -43,17 +43,20 @@ abstract class DurationSerializerTest( @Test + @JsName("test1") fun `zero Duration can be serialized`() { assertEquals(expected = "0", actual = serialize(Duration.ZERO)) } @Test + @JsName("test2") fun `zero Duration can be deserialized`() { assertEquals(expected = Duration.ZERO, actual = deserialize("0")) } @Test + @JsName("test3") fun `infinite Durations cannot be serialized`() { assertFailsWith { serialize(Duration.INFINITE) } assertFailsWith { serialize(-Duration.INFINITE) } @@ -61,38 +64,45 @@ abstract class DurationSerializerTest( @Test + @JsName("test4") fun `positive Duration can be serialized`() { assertEquals(expected = json, actual = serialize(duration)) } @Test + @JsName("test5") fun `positive Duration can be rounded and serialized`() { assertEquals(expected = json, actual = serialize(durationToRound)) } @Test + @JsName("test6") fun `positive Duration can be deserialized`() { assertEquals(expected = duration, actual = deserialize(json)) } @Test + @JsName("test7") fun `negative Duration can be serialized`() { assertEquals(expected = "-$json", actual = serialize(-duration)) } @Test + @JsName("test8") fun `negative Duration can be rounded and serialized`() { assertEquals(expected = "-$json", actual = serialize(-durationToRound)) } @Test + @JsName("test9") fun `negative Duration can be deserialized`() { assertEquals(expected = -duration, actual = deserialize("-$json")) } @Test + @JsName("test10") fun `positive Duration that would overflow in target unit cannot be serialized`() { if (durationThatWouldOverflowInTargetUnit != null) assertFailsWith { serialize(durationThatWouldOverflowInTargetUnit) @@ -100,6 +110,7 @@ abstract class DurationSerializerTest( } @Test + @JsName("test11") fun `negative Duration that would overflow in target unit cannot be serialized`() { if (durationThatWouldOverflowInTargetUnit != null) assertFailsWith { serialize(-durationThatWouldOverflowInTargetUnit) @@ -108,11 +119,13 @@ abstract class DurationSerializerTest( @Test + @JsName("test12") fun `large positive Duration gets deserialized as Infinity`() { if (largeJson != null) assertEquals(expected = Duration.INFINITE, deserialize(largeJson)) } @Test + @JsName("test13") fun `large negative Duration gets deserialized as -Infinity`() { if (largeJson != null) assertEquals(expected = -Duration.INFINITE, deserialize("-$largeJson")) } diff --git a/common/src/test/kotlin/serialization/InstantSerializersTests.kt b/common/src/commonTest/kotlin/serialization/InstantSerializersTests.kt similarity index 89% rename from common/src/test/kotlin/serialization/InstantSerializersTests.kt rename to common/src/commonTest/kotlin/serialization/InstantSerializersTests.kt index ebbe87a3abfa..70ccbd59d53a 100644 --- a/common/src/test/kotlin/serialization/InstantSerializersTests.kt +++ b/common/src/commonTest/kotlin/serialization/InstantSerializersTests.kt @@ -1,11 +1,11 @@ -package serialization +package dev.kord.common.serialization -import dev.kord.common.serialization.InstantInEpochMillisecondsSerializer -import dev.kord.common.serialization.InstantInEpochSecondsSerializer +import dev.kord.test.IgnoreOnJs import kotlinx.datetime.Instant import kotlinx.serialization.KSerializer import kotlinx.serialization.SerializationException import kotlinx.serialization.json.Json +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -29,39 +29,46 @@ abstract class InstantSerializerTest( @Test + @JsName("test1") fun `epoch Instant can be serialized`() { assertEquals(expected = "0", actual = serialize(EPOCH)) } @Test + @JsName("test2") fun `epoch Instant can be deserialized`() { assertEquals(expected = EPOCH, actual = deserialize("0")) } @Test + @JsName("test3") fun `future Instant can be serialized`() { assertEquals(expected = json, actual = serialize(instant)) } @Test + @JsName("test4") fun `future Instant can be deserialized`() { assertEquals(expected = instant, actual = deserialize(json)) } @Test + @JsName("test5") fun `past Instant can be serialized`() { assertEquals(expected = "-$json", actual = serialize(mirroredInstant)) } @Test + @JsName("test6") fun `past Instant can be deserialized`() { assertEquals(expected = mirroredInstant, actual = deserialize("-$json")) } } +@IgnoreOnJs // currently can't pass class InstantInEpochMillisecondsSerializerTest : InstantSerializerTest( json = "796514689159", instant = Instant.fromEpochMilliseconds(796514689159), @@ -71,6 +78,7 @@ class InstantInEpochMillisecondsSerializerTest : InstantSerializerTest( private val pastInstantExactlyAtLimit = Instant.fromEpochMilliseconds(Long.MIN_VALUE) @Test + @JsName("test7") fun `future Instant under limit can be serialized`() { assertEquals( expected = (Long.MAX_VALUE - 1).toString(), @@ -79,6 +87,7 @@ class InstantInEpochMillisecondsSerializerTest : InstantSerializerTest( } @Test + @JsName("test8") fun `past Instant under limit can be serialized`() { assertEquals( expected = Long.MIN_VALUE.toString(), @@ -88,22 +97,26 @@ class InstantInEpochMillisecondsSerializerTest : InstantSerializerTest( @Test + @JsName("test9") fun `future Instant exactly at limit can be serialized`() { assertEquals(expected = Long.MAX_VALUE.toString(), actual = serialize(futureInstantExactlyAtLimit)) } @Test + @JsName("test10") fun `past Instant exactly at limit can be serialized`() { assertEquals(expected = Long.MIN_VALUE.toString(), actual = serialize(pastInstantExactlyAtLimit)) } @Test + @JsName("test11") fun `future Instant over limit cannot be serialized`() { assertFailsWith { serialize(futureInstantExactlyAtLimit + 1.nanoseconds) } } @Test + @JsName("test12") fun `past Instant over limit cannot be serialized`() { assertFailsWith { serialize(pastInstantExactlyAtLimit - 1.nanoseconds) } } diff --git a/common/src/test/resources/json/channel/channelcategory.json b/common/src/commonTest/resources/json/channel/channelcategory.json similarity index 100% rename from common/src/test/resources/json/channel/channelcategory.json rename to common/src/commonTest/resources/json/channel/channelcategory.json diff --git a/common/src/test/resources/json/channel/dmchannel.json b/common/src/commonTest/resources/json/channel/dmchannel.json similarity index 100% rename from common/src/test/resources/json/channel/dmchannel.json rename to common/src/commonTest/resources/json/channel/dmchannel.json diff --git a/common/src/test/resources/json/channel/groupdmchannel.json b/common/src/commonTest/resources/json/channel/groupdmchannel.json similarity index 100% rename from common/src/test/resources/json/channel/groupdmchannel.json rename to common/src/commonTest/resources/json/channel/groupdmchannel.json diff --git a/common/src/test/resources/json/channel/guildnewschannel.json b/common/src/commonTest/resources/json/channel/guildnewschannel.json similarity index 100% rename from common/src/test/resources/json/channel/guildnewschannel.json rename to common/src/commonTest/resources/json/channel/guildnewschannel.json diff --git a/common/src/test/resources/json/channel/guildtextchannel.json b/common/src/commonTest/resources/json/channel/guildtextchannel.json similarity index 100% rename from common/src/test/resources/json/channel/guildtextchannel.json rename to common/src/commonTest/resources/json/channel/guildtextchannel.json diff --git a/common/src/test/resources/json/channel/guildvoicechannel.json b/common/src/commonTest/resources/json/channel/guildvoicechannel.json similarity index 100% rename from common/src/test/resources/json/channel/guildvoicechannel.json rename to common/src/commonTest/resources/json/channel/guildvoicechannel.json diff --git a/common/src/test/resources/json/emoji/customemoji.json b/common/src/commonTest/resources/json/emoji/customemoji.json similarity index 100% rename from common/src/test/resources/json/emoji/customemoji.json rename to common/src/commonTest/resources/json/emoji/customemoji.json diff --git a/common/src/test/resources/json/emoji/emoji.json b/common/src/commonTest/resources/json/emoji/emoji.json similarity index 100% rename from common/src/test/resources/json/emoji/emoji.json rename to common/src/commonTest/resources/json/emoji/emoji.json diff --git a/common/src/test/resources/json/emoji/standardemoji.json b/common/src/commonTest/resources/json/emoji/standardemoji.json similarity index 100% rename from common/src/test/resources/json/emoji/standardemoji.json rename to common/src/commonTest/resources/json/emoji/standardemoji.json diff --git a/common/src/test/resources/json/guild/guild.json b/common/src/commonTest/resources/json/guild/guild.json similarity index 100% rename from common/src/test/resources/json/guild/guild.json rename to common/src/commonTest/resources/json/guild/guild.json diff --git a/common/src/test/resources/json/guild/guildmember.json b/common/src/commonTest/resources/json/guild/guildmember.json similarity index 100% rename from common/src/test/resources/json/guild/guildmember.json rename to common/src/commonTest/resources/json/guild/guildmember.json diff --git a/common/src/test/resources/json/guild/partialguild.json b/common/src/commonTest/resources/json/guild/partialguild.json similarity index 100% rename from common/src/test/resources/json/guild/partialguild.json rename to common/src/commonTest/resources/json/guild/partialguild.json diff --git a/common/src/test/resources/json/guild/unavailableguild.json b/common/src/commonTest/resources/json/guild/unavailableguild.json similarity index 100% rename from common/src/test/resources/json/guild/unavailableguild.json rename to common/src/commonTest/resources/json/guild/unavailableguild.json diff --git a/common/src/test/resources/json/interaction/groupsubcommand.json b/common/src/commonTest/resources/json/interaction/groupsubcommand.json similarity index 100% rename from common/src/test/resources/json/interaction/groupsubcommand.json rename to common/src/commonTest/resources/json/interaction/groupsubcommand.json diff --git a/common/src/test/resources/json/interaction/rootcommand.json b/common/src/commonTest/resources/json/interaction/rootcommand.json similarity index 100% rename from common/src/test/resources/json/interaction/rootcommand.json rename to common/src/commonTest/resources/json/interaction/rootcommand.json diff --git a/common/src/test/resources/json/interaction/selectmenu.json b/common/src/commonTest/resources/json/interaction/selectmenu.json similarity index 100% rename from common/src/test/resources/json/interaction/selectmenu.json rename to common/src/commonTest/resources/json/interaction/selectmenu.json diff --git a/common/src/test/resources/json/interaction/slash_command_permissions_update.json b/common/src/commonTest/resources/json/interaction/slash_command_permissions_update.json similarity index 100% rename from common/src/test/resources/json/interaction/slash_command_permissions_update.json rename to common/src/commonTest/resources/json/interaction/slash_command_permissions_update.json diff --git a/common/src/test/resources/json/interaction/subcommand.json b/common/src/commonTest/resources/json/interaction/subcommand.json similarity index 100% rename from common/src/test/resources/json/interaction/subcommand.json rename to common/src/commonTest/resources/json/interaction/subcommand.json diff --git a/common/src/test/resources/json/message/crossposted.json b/common/src/commonTest/resources/json/message/crossposted.json similarity index 100% rename from common/src/test/resources/json/message/crossposted.json rename to common/src/commonTest/resources/json/message/crossposted.json diff --git a/common/src/test/resources/json/message/message.json b/common/src/commonTest/resources/json/message/message.json similarity index 100% rename from common/src/test/resources/json/message/message.json rename to common/src/commonTest/resources/json/message/message.json diff --git a/common/src/test/resources/json/user/user.json b/common/src/commonTest/resources/json/user/user.json similarity index 100% rename from common/src/test/resources/json/user/user.json rename to common/src/commonTest/resources/json/user/user.json diff --git a/common/src/test/resources/json/voice/voicestate.json b/common/src/commonTest/resources/json/voice/voicestate.json similarity index 100% rename from common/src/test/resources/json/voice/voicestate.json rename to common/src/commonTest/resources/json/voice/voicestate.json diff --git a/common/src/jsMain/kotlin/http/HttpEngine.kt b/common/src/jsMain/kotlin/http/HttpEngine.kt new file mode 100644 index 000000000000..b3d5dcea53f4 --- /dev/null +++ b/common/src/jsMain/kotlin/http/HttpEngine.kt @@ -0,0 +1,8 @@ +package dev.kord.common.http + +import dev.kord.common.annotation.KordInternal +import io.ktor.client.engine.js.* + +/** @suppress */ +@KordInternal +public actual typealias HttpEngine = Js diff --git a/common/src/jvmMain/kotlin/Color.kt b/common/src/jvmMain/kotlin/Color.kt new file mode 100644 index 000000000000..228ac673f2df --- /dev/null +++ b/common/src/jvmMain/kotlin/Color.kt @@ -0,0 +1,3 @@ +package dev.kord.common + +public val java.awt.Color.kColor: Color get() = Color(rgb) diff --git a/common/src/jvmMain/kotlin/ConcurrentHashMap.kt b/common/src/jvmMain/kotlin/ConcurrentHashMap.kt new file mode 100644 index 000000000000..4fb4ddeb7366 --- /dev/null +++ b/common/src/jvmMain/kotlin/ConcurrentHashMap.kt @@ -0,0 +1,7 @@ +package dev.kord.common + +import dev.kord.common.annotation.KordInternal + +/** @suppress */ +@KordInternal +public actual typealias ConcurrentHashMap = java.util.concurrent.ConcurrentHashMap diff --git a/common/src/jvmMain/kotlin/DiscordBitSetJvm.kt b/common/src/jvmMain/kotlin/DiscordBitSetJvm.kt new file mode 100644 index 000000000000..591cae341588 --- /dev/null +++ b/common/src/jvmMain/kotlin/DiscordBitSetJvm.kt @@ -0,0 +1,13 @@ +package dev.kord.common + +import java.math.BigInteger +import java.nio.ByteBuffer + +internal actual fun formatIntegerFromLittleEndianLongArray(data: LongArray): String { + // need to convert from little-endian data to big-endian expected by BigInteger + val buffer = ByteBuffer.allocate(data.size * Long.SIZE_BYTES) + buffer.asLongBuffer().put(data.reversedArray()) + return BigInteger(buffer.array()).toString() +} + +internal actual fun parseIntegerToBigEndianByteArray(value: String): ByteArray = BigInteger(value).toByteArray() diff --git a/common/src/jvmMain/kotlin/Locale.kt b/common/src/jvmMain/kotlin/Locale.kt new file mode 100644 index 000000000000..ee1b63c35c8a --- /dev/null +++ b/common/src/jvmMain/kotlin/Locale.kt @@ -0,0 +1,11 @@ +package dev.kord.common + +/** + * Converts this [dev.kord.common.Locale] into a [java.util.Locale]. + */ +public fun Locale.asJavaLocale(): java.util.Locale = java.util.Locale(language, country ?: "") + +/** + * Converts this [java.util.Locale] into a [dev.kord.common.Locale]. + */ +public val java.util.Locale.kLocale: Locale get() = Locale(language, country.ifBlank { null }) diff --git a/common/src/jvmMain/kotlin/http/HttpEngine.kt b/common/src/jvmMain/kotlin/http/HttpEngine.kt new file mode 100644 index 000000000000..a201c8d46c79 --- /dev/null +++ b/common/src/jvmMain/kotlin/http/HttpEngine.kt @@ -0,0 +1,9 @@ +package dev.kord.common.http + +import dev.kord.common.annotation.KordInternal +import io.ktor.client.engine.* +import io.ktor.client.engine.cio.* + +/** @suppress */ +@KordInternal +public actual object HttpEngine : HttpClientEngineFactory by CIO diff --git a/common/src/jvmTest/kotlin/ColorTestsJvm.kt b/common/src/jvmTest/kotlin/ColorTestsJvm.kt new file mode 100644 index 000000000000..c5e15b31c54c --- /dev/null +++ b/common/src/jvmTest/kotlin/ColorTestsJvm.kt @@ -0,0 +1,16 @@ +package dev.kord.common + +import kotlin.test.assertEquals + +import kotlin.test.Test + +class ColorTestsJvm { + @Test + fun `java to kColor conversion`() { + val color = java.awt.Color.decode("#DBD0B4").kColor + + assertEquals(219, color.red) + assertEquals(208, color.green) + assertEquals(180, color.blue) + } +} diff --git a/common/src/jvmTest/kotlin/entity/SnowflakeTestJvm.kt b/common/src/jvmTest/kotlin/entity/SnowflakeTestJvm.kt new file mode 100644 index 000000000000..604c0a72d558 --- /dev/null +++ b/common/src/jvmTest/kotlin/entity/SnowflakeTestJvm.kt @@ -0,0 +1,15 @@ +package dev.kord.common.entity + +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class SnowflakeTestJvm { + @Test + fun `Snowflake's natural order works with SortedSets`() { + val a = Snowflake(0b0_00000_00000_000000000000_u) + val b = Snowflake(0b0_00000_00000_000000000001_u) + val c = Snowflake(0b1_00000_00000_000000000000_u) + assertEquals(2, sortedSetOf(a, b).size) + assertEquals(2, sortedSetOf(a, c).size) + } +} diff --git a/common/src/nonJvmMain/kotlin/ConcurrentHashMap.kt b/common/src/nonJvmMain/kotlin/ConcurrentHashMap.kt new file mode 100644 index 000000000000..be329858c821 --- /dev/null +++ b/common/src/nonJvmMain/kotlin/ConcurrentHashMap.kt @@ -0,0 +1,8 @@ +package dev.kord.common + +import co.touchlab.stately.collections.ConcurrentMutableMap +import dev.kord.common.annotation.KordInternal + +/** @suppress */ +@KordInternal +public actual typealias ConcurrentHashMap = ConcurrentMutableMap diff --git a/common/src/nonJvmMain/kotlin/DiscordBitSet.kt b/common/src/nonJvmMain/kotlin/DiscordBitSet.kt new file mode 100644 index 000000000000..3c0e5f121a3e --- /dev/null +++ b/common/src/nonJvmMain/kotlin/DiscordBitSet.kt @@ -0,0 +1,15 @@ +package dev.kord.common + +import com.ionspin.kotlin.bignum.integer.BigInteger +import com.ionspin.kotlin.bignum.integer.Sign +import io.ktor.utils.io.core.* + +internal actual fun formatIntegerFromLittleEndianLongArray(data: LongArray) = + withBuffer(data.size * Long.SIZE_BYTES) { + // need to convert from little-endian data to big-endian expected by BigInteger + writeFully(data.reversedArray()) + BigInteger.fromByteArray(readBytes(), Sign.POSITIVE).toString() + } + +internal actual fun parseIntegerToBigEndianByteArray(value: String): ByteArray = + BigInteger.parseString(value).toByteArray() diff --git a/core-voice/README.md b/core-voice/README.md new file mode 100644 index 000000000000..199acba8f34a --- /dev/null +++ b/core-voice/README.md @@ -0,0 +1,4 @@ +# core-voice + +This Module adds extensions to [core](../core) for [kord-voice](../voice). Please read the [voice](../voice) +documentation for more information diff --git a/core-voice/api/core-voice.api b/core-voice/api/core-voice.api new file mode 100644 index 000000000000..fde1322aa8fe --- /dev/null +++ b/core-voice/api/core-voice.api @@ -0,0 +1,4 @@ +public final class dev/kord/core/behavior/channel/VoiceBaseVoiceChannelBehavior { + public static final fun connect (Ldev/kord/core/behavior/channel/BaseVoiceChannelBehavior;Lkotlin/jvm/functions/Function1;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + diff --git a/core-voice/build.gradle.kts b/core-voice/build.gradle.kts new file mode 100644 index 000000000000..356fca4c82b8 --- /dev/null +++ b/core-voice/build.gradle.kts @@ -0,0 +1,9 @@ +plugins { + `kord-module` + `kord-publishing` +} + +dependencies { + api(projects.core) + api(projects.voice) +} diff --git a/core/src/voice/kotlin/dev/kord/core/behavior/channel/BaseVoiceChannelBehavior.kt b/core-voice/src/main/kotlin/BaseVoiceChannelBehaviorExtensions.kt similarity index 90% rename from core/src/voice/kotlin/dev/kord/core/behavior/channel/BaseVoiceChannelBehavior.kt rename to core-voice/src/main/kotlin/BaseVoiceChannelBehaviorExtensions.kt index b5c920d7f0e0..c6da181516d1 100644 --- a/core/src/voice/kotlin/dev/kord/core/behavior/channel/BaseVoiceChannelBehavior.kt +++ b/core-voice/src/main/kotlin/BaseVoiceChannelBehaviorExtensions.kt @@ -17,7 +17,7 @@ import dev.kord.voice.VoiceConnectionBuilder * @return a [VoiceConnection] representing the connection to this [VoiceConnection]. */ @KordVoice -suspend fun BaseVoiceChannelBehavior.connect(builder: VoiceConnectionBuilder.() -> Unit): VoiceConnection { +public suspend fun BaseVoiceChannelBehavior.connect(builder: VoiceConnectionBuilder.() -> Unit): VoiceConnection { val voiceConnection = VoiceConnection( guild.gateway ?: GatewayNotFoundException.voiceConnectionGatewayNotFound(guildId), kord.selfId, diff --git a/core/README.md b/core/README.md index 38e5988f516b..01d53ad43a6d 100644 --- a/core/README.md +++ b/core/README.md @@ -99,7 +99,7 @@ dependencies { dev.kord - kord-core + kord-core-jvm {version} ``` diff --git a/core/api/core.api b/core/api/core.api index 3920b33bd7eb..3c38ed0f8ef4 100644 --- a/core/api/core.api +++ b/core/api/core.api @@ -2085,15 +2085,14 @@ public final class dev/kord/core/builder/components/ButtonBuilderExtensionsKt { public static final fun emoji (Ldev/kord/rest/builder/component/ButtonBuilder;Ldev/kord/core/entity/ReactionEmoji$Unicode;)V } -public final class dev/kord/core/builder/kord/KordBuilder { - public fun (Ljava/lang/String;)V - public final fun build (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +public abstract class dev/kord/core/builder/kord/BaseKordBuilder { + public fun build (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + protected final fun buildBase (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun cache (Lkotlin/jvm/functions/Function2;)V public final fun gateways (Lkotlin/jvm/functions/Function2;)V public final fun getApplicationId ()Ldev/kord/common/entity/Snowflake; public final fun getDefaultDispatcher ()Lkotlinx/coroutines/CoroutineDispatcher; public final fun getDefaultStrategy ()Ldev/kord/core/supplier/EntitySupplyStrategy; - public final fun getEnableShutdownHook ()Z public final fun getEventFlow ()Lkotlinx/coroutines/flow/MutableSharedFlow; public final fun getGatewayEventInterceptor ()Ldev/kord/core/gateway/handler/GatewayEventInterceptor; public final fun getHttpClient ()Lio/ktor/client/HttpClient; @@ -2103,7 +2102,6 @@ public final class dev/kord/core/builder/kord/KordBuilder { public final fun setApplicationId (Ldev/kord/common/entity/Snowflake;)V public final fun setDefaultDispatcher (Lkotlinx/coroutines/CoroutineDispatcher;)V public final fun setDefaultStrategy (Ldev/kord/core/supplier/EntitySupplyStrategy;)V - public final fun setEnableShutdownHook (Z)V public final fun setEventFlow (Lkotlinx/coroutines/flow/MutableSharedFlow;)V public final fun setGatewayEventInterceptor (Ldev/kord/core/gateway/handler/GatewayEventInterceptor;)V public final fun setHttpClient (Lio/ktor/client/HttpClient;)V @@ -2111,11 +2109,21 @@ public final class dev/kord/core/builder/kord/KordBuilder { public final fun sharding (Lkotlin/jvm/functions/Function1;)V } +public final class dev/kord/core/builder/kord/KordBuilder : dev/kord/core/builder/kord/BaseKordBuilder { + public fun (Ljava/lang/String;)V + public fun build (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; + public final fun getEnableShutdownHook ()Z + public final fun setEnableShutdownHook (Z)V +} + public final class dev/kord/core/builder/kord/KordBuilderKt { public static final synthetic fun invoke (Ldev/kord/gateway/DefaultGateway$Companion;Ldev/kord/core/ClientResources;Ldev/kord/gateway/retry/Retry;)Ldev/kord/gateway/DefaultGateway; public static synthetic fun invoke$default (Ldev/kord/gateway/DefaultGateway$Companion;Ldev/kord/core/ClientResources;Ldev/kord/gateway/retry/Retry;ILjava/lang/Object;)Ldev/kord/gateway/DefaultGateway; } +public final class dev/kord/core/builder/kord/KordBuilderUtilKt { +} + public final class dev/kord/core/builder/kord/KordProxyBuilder : dev/kord/core/builder/kord/RestOnlyBuilder { public fun (Ldev/kord/common/entity/Snowflake;)V public fun getApplicationId ()Ldev/kord/common/entity/Snowflake; @@ -2185,8 +2193,6 @@ public final class dev/kord/core/cache/KordCacheBuilder { public final fun forDescription (Ldev/kord/cache/api/data/DataDescription;Lkotlin/jvm/functions/Function2;)V public final fun getDefaultGenerator ()Lkotlin/jvm/functions/Function2; public final fun guilds (Lkotlin/jvm/functions/Function2;)V - public final fun lruCache (I)Lkotlin/jvm/functions/Function2; - public static synthetic fun lruCache$default (Ldev/kord/core/cache/KordCacheBuilder;IILjava/lang/Object;)Lkotlin/jvm/functions/Function2; public final fun members (Lkotlin/jvm/functions/Function2;)V public final fun messages (Lkotlin/jvm/functions/Function2;)V public final fun none ()Lkotlin/jvm/functions/Function2; @@ -2199,6 +2205,11 @@ public final class dev/kord/core/cache/KordCacheBuilder { public final fun webhooks (Lkotlin/jvm/functions/Function2;)V } +public final class dev/kord/core/cache/KordCacheBuilderKt { + public static final fun lruCache (Ldev/kord/core/cache/KordCacheBuilder;I)Lkotlin/jvm/functions/Function2; + public static synthetic fun lruCache$default (Ldev/kord/core/cache/KordCacheBuilder;IILjava/lang/Object;)Lkotlin/jvm/functions/Function2; +} + public final class dev/kord/core/cache/QueryKt { public static final fun booleanEq (Ldev/kord/cache/api/QueryBuilder;Lkotlin/reflect/KProperty1;Ljava/lang/Boolean;)V public static final fun idEq (Ldev/kord/cache/api/QueryBuilder;Lkotlin/reflect/KProperty1;Ldev/kord/common/entity/Snowflake;)V @@ -6144,7 +6155,7 @@ public final class dev/kord/core/entity/Guild : dev/kord/core/behavior/GuildBeha public final fun getOwnerId ()Ldev/kord/common/entity/Snowflake; public final fun getOwnerOrNull (Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public final fun getPermissions ()Ldev/kord/common/entity/Permissions; - public final fun getPreferredLocale ()Ljava/util/Locale; + public final fun getPreferredLocale ()Ldev/kord/common/Locale; public final fun getPremiumProgressBarEnabled ()Z public final fun getPremiumSubscriptionCount ()Ljava/lang/Integer; public final fun getPremiumTier ()Ldev/kord/common/entity/PremiumTier; diff --git a/core/build.gradle.kts b/core/build.gradle.kts index e65161ba483c..58bca499628c 100644 --- a/core/build.gradle.kts +++ b/core/build.gradle.kts @@ -1,42 +1,40 @@ plugins { - java - `kord-module` - `kord-sampled-module` + `kord-multiplatform-module` `kord-publishing` } -val voice: SourceSet by sourceSets.creating -val voiceApi: Configuration by configurations.getting - -configurations { - getByName("voiceImplementation") { - extendsFrom(implementation.get()) +kotlin { + js { + nodejs { + testTask { + useMocha { + timeout = "10000" // KordEventDropTest is too slow for default 2 seconds timeout + } + } + } } -} - -dependencies { - api(projects.common) - api(projects.rest) - api(projects.gateway) - voiceApi(projects.core) - voiceApi(projects.voice) - - api(libs.kord.cache.api) - api(libs.kord.cache.map) - ksp(projects.kspProcessors) - - samplesImplementation(libs.slf4j.simple) - - testImplementation(libs.bundles.test.implementation) - testRuntimeOnly(libs.bundles.test.runtime) + sourceSets { + commonMain { + dependencies { + api(projects.common) + api(projects.rest) + api(projects.gateway) + + api(libs.kord.cache.api) + api(libs.kord.cache.map) + } + } + jvmTest { + dependencies { + implementation(libs.mockk) + } + } + } } -java { - registerFeature("voice") { - usingSourceSet(voice) - withJavadocJar() - withSourcesJar() - capability("dev.kord", "core-voice", version as String) +tasks { + dokkaHtmlMultiModule { + enabled = false } } diff --git a/core/live-tests/build.gradle.kts b/core/live-tests/build.gradle.kts new file mode 100644 index 000000000000..86fe49a30fc1 --- /dev/null +++ b/core/live-tests/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + `kord-internal-multiplatform-module` +} + +kotlin { + sourceSets { + all { + applyKordOptIns() + } + commonTest { + dependencies { + implementation(projects.core) + implementation(projects.testKit) + } + } + } +} + +tasks { + withType().configureEach { + enabled = !System.getenv("KORD_TEST_TOKEN").isNullOrBlank() + } +} diff --git a/core/live-tests/src/commonTest/kotlin/KordTest.kt b/core/live-tests/src/commonTest/kotlin/KordTest.kt new file mode 100644 index 000000000000..c91db63b330a --- /dev/null +++ b/core/live-tests/src/commonTest/kotlin/KordTest.kt @@ -0,0 +1,18 @@ +package dev.kord.core + +import dev.kord.core.event.gateway.ReadyEvent +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertFalse + +internal class KordTest { + @Test + @JsName("test1") + fun `Kord life cycle is correctly ended on shutdown`() = runTest { + val kord = Kord.restOnly(testToken) + val job = kord.on {} + kord.shutdown() + assertFalse(job.isActive) + } +} diff --git a/core/live-tests/src/commonTest/kotlin/StrategyTest.kt b/core/live-tests/src/commonTest/kotlin/StrategyTest.kt new file mode 100644 index 000000000000..d7c0a9837ff7 --- /dev/null +++ b/core/live-tests/src/commonTest/kotlin/StrategyTest.kt @@ -0,0 +1,52 @@ +package dev.kord.core + +import dev.kord.cache.api.put +import dev.kord.core.supplier.EntitySupplyStrategy +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertNotNull +import kotlin.test.assertNull + +class StrategyTest { + + @Test + @JsName("test1") + fun `rest only`() = runTest { + withKord { kord -> + val fromRest = kord.with(EntitySupplyStrategy.rest).getSelfOrNull() + val inCache = kord.with(EntitySupplyStrategy.cache).getSelfOrNull() + assertNull(inCache) + assertNotNull(fromRest) + } + } + + @Test + @JsName("test2") + fun `cache only`() = runTest { + withKord { kord -> + kord.cache.put(kord.getSelf().data) + val inCache = kord.with(EntitySupplyStrategy.cache).getSelfOrNull() + assertNotNull(inCache) + } + } + + @Test + @JsName("test3") + fun `cache falls back to rest`() = runTest { + withKord { kord -> + val cache = kord.with(EntitySupplyStrategy.cache) + val inCache = cache.getSelfOrNull() + + assertNull(inCache) + + val self = kord.getSelf() + assertNotNull(self) + kord.cache.put(self.data) + + assertEquals(self, cache.getSelf()) + + } + } +} diff --git a/core/live-tests/src/commonTest/kotlin/TestToken.kt b/core/live-tests/src/commonTest/kotlin/TestToken.kt new file mode 100644 index 000000000000..3634fddf977e --- /dev/null +++ b/core/live-tests/src/commonTest/kotlin/TestToken.kt @@ -0,0 +1,42 @@ +package dev.kord.core + +import dev.kord.cache.map.MapDataCache +import dev.kord.core.builder.kord.configure +import dev.kord.core.builder.kord.getBotIdFromToken +import dev.kord.core.cache.registerKordData +import dev.kord.core.gateway.DefaultMasterGateway +import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor +import dev.kord.core.regression.CrashingHandler +import dev.kord.core.regression.FakeGateway +import dev.kord.core.supplier.EntitySupplyStrategy +import dev.kord.gateway.builder.Shards +import dev.kord.rest.service.RestClient +import dev.kord.test.getEnv +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableSharedFlow + +val testToken = getEnv("KORD_TEST_TOKEN") ?: error("KORD_TEST_TOKEN is not defined") + +suspend inline fun withKord(block: (kord: Kord) -> Unit) { + val token = testToken + val resources = ClientResources( + token, + getBotIdFromToken(token), + Shards(1), + maxConcurrency = 1, + null.configure(), + EntitySupplyStrategy.cacheWithRestFallback, + ) + val kord = Kord( + resources, + MapDataCache().also { it.registerKordData() }, + DefaultMasterGateway(mapOf(0 to FakeGateway)), + RestClient(CrashingHandler(resources.httpClient, resources.token)), + getBotIdFromToken(token), + MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE), + Dispatchers.Default, + DefaultGatewayEventInterceptor(), + ) + block(kord) + kord.shutdown() +} diff --git a/core/src/test/kotlin/regression/CacheMissRegression.kt b/core/live-tests/src/commonTest/kotlin/regression/CacheMissRegression.kt similarity index 64% rename from core/src/test/kotlin/regression/CacheMissRegression.kt rename to core/live-tests/src/commonTest/kotlin/regression/CacheMissRegression.kt index eba4327ae36a..e547779900c6 100644 --- a/core/src/test/kotlin/regression/CacheMissRegression.kt +++ b/core/live-tests/src/commonTest/kotlin/regression/CacheMissRegression.kt @@ -1,29 +1,19 @@ -package regression +package dev.kord.core.regression import dev.kord.cache.api.put -import dev.kord.cache.map.MapDataCache import dev.kord.common.entity.ChannelType import dev.kord.common.entity.Snowflake -import dev.kord.core.ClientResources -import dev.kord.core.Kord -import dev.kord.core.builder.kord.configure -import dev.kord.core.builder.kord.getBotIdFromToken import dev.kord.core.cache.data.ChannelData -import dev.kord.core.cache.registerKordData -import dev.kord.core.gateway.DefaultMasterGateway -import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor -import dev.kord.core.supplier.EntitySupplyStrategy +import dev.kord.core.withKord import dev.kord.gateway.Command import dev.kord.gateway.Event import dev.kord.gateway.Gateway import dev.kord.gateway.GatewayConfiguration -import dev.kord.gateway.builder.Shards import dev.kord.rest.request.JsonRequest import dev.kord.rest.request.MultipartRequest import dev.kord.rest.request.Request import dev.kord.rest.request.RequestHandler import dev.kord.rest.route.Route -import dev.kord.rest.service.RestClient import io.ktor.client.* import io.ktor.client.request.* import io.ktor.client.request.forms.* @@ -31,22 +21,19 @@ import io.ktor.client.statement.* import io.ktor.content.* import io.ktor.http.* import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.runBlocking import kotlinx.coroutines.test.runTest import kotlinx.serialization.SerializationStrategy import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.assertThrows -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext -import kotlin.test.BeforeTest +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertFailsWith import kotlin.time.Duration @@ -116,52 +103,25 @@ class CrashingHandler(val client: HttpClient, override val token: String) : Requ } } -@EnabledIfEnvironmentVariable(named = "KORD_TEST_TOKEN", matches = ".+") class CacheMissingRegressions { - lateinit var kord: Kord - - @BeforeTest - fun setup() = runTest { //TODO, move this over to entity supplier tests instead, eventually. - val token = System.getenv("KORD_TEST_TOKEN") - val resources = ClientResources( - token, - getBotIdFromToken(token), - Shards(1), - maxConcurrency = 1, - null.configure(), - EntitySupplyStrategy.cacheWithRestFallback, - ) - kord = Kord( - resources, - MapDataCache().also { it.registerKordData() }, - DefaultMasterGateway(mapOf(0 to FakeGateway)), - RestClient(CrashingHandler(resources.httpClient, resources.token)), - getBotIdFromToken(token), - MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE), - Dispatchers.Default, - DefaultGatewayEventInterceptor(), - ) - } - @Test - fun `if data not in cache explode`() { - val id = 5uL - assertThrows { - runBlocking { - kord.getChannel(Snowflake(id)) - } + @JsName("test1") + fun `if data not in cache explode`() = runTest { + withKord { kord -> + val id = 5uL + assertFailsWith { kord.getChannel(Snowflake(id)) } } } @Test - fun `if data in cache don't fetch from rest`() { - runBlocking { + @JsName("test2") + fun `if data in cache don't fetch from rest`() = runTest { + withKord { kord -> val id = Snowflake(5uL) kord.cache.put(ChannelData(id, ChannelType.GuildText)) kord.getChannel(id) } } - } diff --git a/core/src/main/kotlin/ClientResources.kt b/core/src/commonMain/kotlin/ClientResources.kt similarity index 100% rename from core/src/main/kotlin/ClientResources.kt rename to core/src/commonMain/kotlin/ClientResources.kt diff --git a/core/src/main/kotlin/Kord.kt b/core/src/commonMain/kotlin/Kord.kt similarity index 100% rename from core/src/main/kotlin/Kord.kt rename to core/src/commonMain/kotlin/Kord.kt diff --git a/core/src/main/kotlin/KordObject.kt b/core/src/commonMain/kotlin/KordObject.kt similarity index 100% rename from core/src/main/kotlin/KordObject.kt rename to core/src/commonMain/kotlin/KordObject.kt diff --git a/core/src/main/kotlin/Unsafe.kt b/core/src/commonMain/kotlin/Unsafe.kt similarity index 100% rename from core/src/main/kotlin/Unsafe.kt rename to core/src/commonMain/kotlin/Unsafe.kt diff --git a/core/src/main/kotlin/Util.kt b/core/src/commonMain/kotlin/Util.kt similarity index 99% rename from core/src/main/kotlin/Util.kt rename to core/src/commonMain/kotlin/Util.kt index 49e8e660a499..827510177165 100644 --- a/core/src/main/kotlin/Util.kt +++ b/core/src/commonMain/kotlin/Util.kt @@ -476,3 +476,6 @@ public fun Intents.IntentsBuilder.enableEvent(event: KClass): Unit = else -> Unit } + +// Replacement of Objects.hash +internal fun hash(vararg values: Any?) = values.contentHashCode() diff --git a/core/src/main/kotlin/behavior/ChatInputCommandBehavior.kt b/core/src/commonMain/kotlin/behavior/ChatInputCommandBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/ChatInputCommandBehavior.kt rename to core/src/commonMain/kotlin/behavior/ChatInputCommandBehavior.kt diff --git a/core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt b/core/src/commonMain/kotlin/behavior/GlobalApplicationCommandBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/GlobalApplicationCommandBehavior.kt rename to core/src/commonMain/kotlin/behavior/GlobalApplicationCommandBehavior.kt diff --git a/core/src/main/kotlin/behavior/GuildBehavior.kt b/core/src/commonMain/kotlin/behavior/GuildBehavior.kt similarity index 99% rename from core/src/main/kotlin/behavior/GuildBehavior.kt rename to core/src/commonMain/kotlin/behavior/GuildBehavior.kt index d557377c5af0..e7899b7ac8c6 100644 --- a/core/src/main/kotlin/behavior/GuildBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/GuildBehavior.kt @@ -22,6 +22,7 @@ import dev.kord.core.entity.channel.* import dev.kord.core.entity.channel.thread.ThreadChannel import dev.kord.core.event.guild.MembersChunkEvent import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.* import dev.kord.core.supplier.EntitySupplyStrategy.Companion.rest import dev.kord.gateway.Gateway @@ -53,7 +54,6 @@ import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.* import kotlinx.coroutines.flow.* import kotlinx.datetime.Instant -import java.util.Objects import kotlin.contracts.InvocationKind import kotlin.contracts.InvocationKind.EXACTLY_ONCE import kotlin.contracts.contract @@ -677,7 +677,7 @@ public fun GuildBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is GuildBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/GuildEmojiBehavior.kt b/core/src/commonMain/kotlin/behavior/GuildEmojiBehavior.kt similarity index 97% rename from core/src/main/kotlin/behavior/GuildEmojiBehavior.kt rename to core/src/commonMain/kotlin/behavior/GuildEmojiBehavior.kt index 31242215bdce..d71f3aa431bc 100644 --- a/core/src/main/kotlin/behavior/GuildEmojiBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/GuildEmojiBehavior.kt @@ -6,11 +6,11 @@ import dev.kord.core.cache.data.EmojiData import dev.kord.core.entity.KordEntity import dev.kord.core.entity.GuildEmoji import dev.kord.core.entity.Strategizable +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.guild.EmojiModifyBuilder import dev.kord.rest.request.RestRequestException -import java.util.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -57,7 +57,7 @@ internal fun GuildEmojiBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is GuildEmojiBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/GuildScheduledEventBehavior.kt b/core/src/commonMain/kotlin/behavior/GuildScheduledEventBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/GuildScheduledEventBehavior.kt rename to core/src/commonMain/kotlin/behavior/GuildScheduledEventBehavior.kt diff --git a/core/src/main/kotlin/behavior/MemberBehavior.kt b/core/src/commonMain/kotlin/behavior/MemberBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/MemberBehavior.kt rename to core/src/commonMain/kotlin/behavior/MemberBehavior.kt index 59ac4763568b..341825bf4fbe 100644 --- a/core/src/main/kotlin/behavior/MemberBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/MemberBehavior.kt @@ -11,12 +11,12 @@ import dev.kord.core.cache.data.VoiceStateData import dev.kord.core.cache.idEq import dev.kord.core.entity.* import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.ban.BanCreateBuilder import dev.kord.rest.builder.member.MemberModifyBuilder import dev.kord.rest.request.RestRequestException -import java.util.Objects import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -193,7 +193,7 @@ public fun MemberBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is MemberBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/MessageBehavior.kt b/core/src/commonMain/kotlin/behavior/MessageBehavior.kt similarity index 99% rename from core/src/main/kotlin/behavior/MessageBehavior.kt rename to core/src/commonMain/kotlin/behavior/MessageBehavior.kt index 1619b4d2b128..fbf1b2e01ce1 100644 --- a/core/src/main/kotlin/behavior/MessageBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/MessageBehavior.kt @@ -20,7 +20,7 @@ import dev.kord.rest.builder.message.modify.WebhookMessageModifyBuilder import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.RestClient import kotlinx.coroutines.flow.Flow -import java.util.Objects +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -229,7 +229,7 @@ public fun MessageBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is MessageBehavior -> other.id == id && other.channelId == channelId diff --git a/core/src/main/kotlin/behavior/MessageCommandBehavior.kt b/core/src/commonMain/kotlin/behavior/MessageCommandBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/MessageCommandBehavior.kt rename to core/src/commonMain/kotlin/behavior/MessageCommandBehavior.kt diff --git a/core/src/main/kotlin/behavior/RoleBehavior.kt b/core/src/commonMain/kotlin/behavior/RoleBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/RoleBehavior.kt rename to core/src/commonMain/kotlin/behavior/RoleBehavior.kt index 281568185990..66850198adf8 100644 --- a/core/src/main/kotlin/behavior/RoleBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/RoleBehavior.kt @@ -8,6 +8,7 @@ import dev.kord.core.entity.KordEntity import dev.kord.core.entity.Role import dev.kord.core.entity.Strategizable import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.indexOfFirstOrNull import dev.kord.core.sorted import dev.kord.core.supplier.EntitySupplier @@ -17,7 +18,6 @@ import dev.kord.rest.request.RestRequestException import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.map -import java.util.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -129,7 +129,7 @@ public fun RoleBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is RoleBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/StageInstanceBehavior.kt b/core/src/commonMain/kotlin/behavior/StageInstanceBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/StageInstanceBehavior.kt rename to core/src/commonMain/kotlin/behavior/StageInstanceBehavior.kt diff --git a/core/src/main/kotlin/behavior/StickerBehavior.kt b/core/src/commonMain/kotlin/behavior/StickerBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/StickerBehavior.kt rename to core/src/commonMain/kotlin/behavior/StickerBehavior.kt diff --git a/core/src/main/kotlin/behavior/TemplateBehavior.kt b/core/src/commonMain/kotlin/behavior/TemplateBehavior.kt similarity index 96% rename from core/src/main/kotlin/behavior/TemplateBehavior.kt rename to core/src/commonMain/kotlin/behavior/TemplateBehavior.kt index e81cfa207236..7ed3674b675c 100644 --- a/core/src/main/kotlin/behavior/TemplateBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/TemplateBehavior.kt @@ -8,7 +8,7 @@ import dev.kord.core.entity.Guild import dev.kord.core.entity.Template import dev.kord.rest.builder.template.GuildFromTemplateCreateBuilder import dev.kord.rest.builder.template.GuildTemplateModifyBuilder -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -52,7 +52,7 @@ public fun TemplateBehavior(guildId: Snowflake, code: String, kord: Kord): Templ override val guildId: Snowflake = guildId override val kord: Kord = kord - override fun hashCode(): Int = Objects.hash(code) + override fun hashCode(): Int = hash(code) override fun equals(other: Any?): Boolean = other is TemplateBehavior && other.code == code diff --git a/core/src/main/kotlin/behavior/ThreadMemberBehavior.kt b/core/src/commonMain/kotlin/behavior/ThreadMemberBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/ThreadMemberBehavior.kt rename to core/src/commonMain/kotlin/behavior/ThreadMemberBehavior.kt diff --git a/core/src/main/kotlin/behavior/UserBehavior.kt b/core/src/commonMain/kotlin/behavior/UserBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/UserBehavior.kt rename to core/src/commonMain/kotlin/behavior/UserBehavior.kt index 0a91a7998f2e..bc4bfe226e60 100644 --- a/core/src/main/kotlin/behavior/UserBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/UserBehavior.kt @@ -15,7 +15,7 @@ import dev.kord.rest.json.request.DMCreateRequest import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.RestClient import io.ktor.http.* -import java.util.* +import dev.kord.core.hash /** * The behavior of a [Discord User](https://discord.com/developers/docs/resources/user) @@ -145,7 +145,7 @@ public fun UserBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is UserBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/UserCommandBehavior.kt b/core/src/commonMain/kotlin/behavior/UserCommandBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/UserCommandBehavior.kt rename to core/src/commonMain/kotlin/behavior/UserCommandBehavior.kt diff --git a/core/src/main/kotlin/behavior/WebhookBehavior.kt b/core/src/commonMain/kotlin/behavior/WebhookBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/WebhookBehavior.kt rename to core/src/commonMain/kotlin/behavior/WebhookBehavior.kt index b70f37fca7cc..9fae71abca0d 100644 --- a/core/src/main/kotlin/behavior/WebhookBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/WebhookBehavior.kt @@ -15,7 +15,7 @@ import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.message.create.WebhookMessageCreateBuilder import dev.kord.rest.builder.webhook.WebhookModifyBuilder import dev.kord.rest.request.RestRequestException -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -102,7 +102,7 @@ internal fun WebhookBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is WebhookBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt b/core/src/commonMain/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt similarity index 99% rename from core/src/main/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt rename to core/src/commonMain/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt index a8d2359722c4..9da181c459f5 100644 --- a/core/src/main/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/automoderation/AutoModerationRuleBehavior.kt @@ -17,7 +17,7 @@ import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.automoderation.* import dev.kord.rest.request.RestRequestException -import java.util.Objects +import dev.kord.core.hash import kotlin.contracts.InvocationKind.EXACTLY_ONCE import kotlin.contracts.contract @@ -106,7 +106,7 @@ internal class AutoModerationRuleBehaviorImpl( internal fun AutoModerationRuleBehavior.autoModerationRuleEquals(other: Any?) = this === other || (other is AutoModerationRuleBehavior && this.id == other.id && this.guildId == other.guildId) -internal fun AutoModerationRuleBehavior.autoModerationRuleHashCode() = Objects.hash(id, guildId) +internal fun AutoModerationRuleBehavior.autoModerationRuleHashCode() = hash(id, guildId) /** * Requests to edit this [AutoModerationRule] and returns the edited rule. diff --git a/core/src/main/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/BaseVoiceChannelBehavior.kt diff --git a/core/src/main/kotlin/behavior/channel/CategorizableChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/CategorizableChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/CategorizableChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/CategorizableChannelBehavior.kt index 21c4a0d5297e..9b1f843ca237 100644 --- a/core/src/main/kotlin/behavior/channel/CategorizableChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/CategorizableChannelBehavior.kt @@ -17,7 +17,7 @@ import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.RestClient import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -110,7 +110,7 @@ internal fun CategorizableChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/CategoryBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/CategoryBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/CategoryBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/CategoryBehavior.kt index ee163b1d680c..e7057d60a8b2 100644 --- a/core/src/main/kotlin/behavior/channel/CategoryBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/CategoryBehavior.kt @@ -22,7 +22,7 @@ import dev.kord.rest.service.patchCategory import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.filterIsInstance -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -101,7 +101,7 @@ public fun CategoryBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is TopGuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/ChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/ChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt index 5db6749f6f36..42ffd8272b1c 100644 --- a/core/src/main/kotlin/behavior/channel/ChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/ChannelBehavior.kt @@ -12,7 +12,7 @@ import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.core.supplier.getChannelOf import dev.kord.core.supplier.getChannelOfOrNull import dev.kord.rest.request.RestRequestException -import java.util.* +import dev.kord.core.hash /** * The behavior of a [Discord Channel](https://discord.com/developers/docs/resources/channel) @@ -101,7 +101,7 @@ public fun ChannelBehavior(id: Snowflake, kord: Kord, strategy: EntitySupplyStra override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is ChannelBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/channel/ForumChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/ForumChannelBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/channel/ForumChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/ForumChannelBehavior.kt diff --git a/core/src/main/kotlin/behavior/channel/GuildChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/GuildChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/GuildChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/GuildChannelBehavior.kt index 06a1a066512d..63640b2ad495 100644 --- a/core/src/main/kotlin/behavior/channel/GuildChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/GuildChannelBehavior.kt @@ -12,7 +12,7 @@ import dev.kord.core.entity.channel.TopGuildChannel import dev.kord.core.exception.EntityNotFoundException import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash /** * The behavior of a Discord channel associated to a [guild]. @@ -110,7 +110,7 @@ public fun GuildChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/GuildMessageChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/GuildMessageChannelBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/channel/GuildMessageChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/GuildMessageChannelBehavior.kt diff --git a/core/src/main/kotlin/behavior/channel/MessageChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/MessageChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/MessageChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/MessageChannelBehavior.kt index 88854a12b8b4..76702092614b 100644 --- a/core/src/main/kotlin/behavior/channel/MessageChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/MessageChannelBehavior.kt @@ -8,6 +8,7 @@ import dev.kord.core.entity.Message import dev.kord.core.entity.Strategizable import dev.kord.core.entity.channel.MessageChannel import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.message.EmbedBuilder @@ -25,9 +26,9 @@ import kotlinx.coroutines.flow.takeWhile import kotlinx.coroutines.launch import kotlinx.datetime.Clock import kotlinx.datetime.Instant -import java.util.Objects import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.js.JsName import kotlin.time.Duration.Companion.seconds import kotlin.time.TimeMark @@ -212,6 +213,7 @@ public interface MessageChannelBehavior : ChannelBehavior, Strategizable { * * @throws [RestRequestException] if something went wrong during the request. */ + @JsName("sendTyping") // otherwise clashes with Channel.type property public suspend fun type() { kord.rest.channel.triggerTypingIndicator(id) } @@ -259,7 +261,7 @@ public fun MessageChannelBehavior( override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is ChannelBehavior -> other.id == id diff --git a/core/src/main/kotlin/behavior/channel/NewsChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/NewsChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/NewsChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/NewsChannelBehavior.kt index d188f66af30a..8c8bdf030cf3 100644 --- a/core/src/main/kotlin/behavior/channel/NewsChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/NewsChannelBehavior.kt @@ -25,7 +25,7 @@ import dev.kord.rest.service.patchNewsChannel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.datetime.Instant -import java.util.Objects +import dev.kord.core.hash import kotlin.DeprecationLevel.ERROR import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -156,7 +156,7 @@ public fun NewsChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/StageChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/StageChannelBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/channel/StageChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/StageChannelBehavior.kt diff --git a/core/src/main/kotlin/behavior/channel/TextChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/TextChannelBehavior.kt similarity index 99% rename from core/src/main/kotlin/behavior/channel/TextChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/TextChannelBehavior.kt index f4c33a8f91b0..49e6cfab04f0 100644 --- a/core/src/main/kotlin/behavior/channel/TextChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/TextChannelBehavior.kt @@ -23,7 +23,7 @@ import dev.kord.rest.service.patchTextChannel import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filterIsInstance import kotlinx.datetime.Instant -import java.util.* +import dev.kord.core.hash import kotlin.DeprecationLevel.ERROR import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -170,7 +170,7 @@ public fun TextChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/TopGuildChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/TopGuildChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/TopGuildChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/TopGuildChannelBehavior.kt index cc6f0bec0565..ed93a4edbe77 100644 --- a/core/src/main/kotlin/behavior/channel/TopGuildChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/TopGuildChannelBehavior.kt @@ -14,7 +14,7 @@ import dev.kord.rest.service.editMemberPermissions import dev.kord.rest.service.editRolePermission import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.withIndex -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -103,7 +103,7 @@ internal fun TopGuildChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt index 8a930746d006..106b2173185b 100644 --- a/core/src/main/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/TopGuildMessageChannelBehavior.kt @@ -9,8 +9,8 @@ import dev.kord.core.exception.EntityNotFoundException import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.webhook.WebhookCreateBuilder -import java.util.* import kotlin.DeprecationLevel.HIDDEN +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -78,7 +78,7 @@ internal fun TopGuildMessageChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/VoiceChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/VoiceChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/VoiceChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/VoiceChannelBehavior.kt index caa781deadd8..0c1b1ed48748 100644 --- a/core/src/main/kotlin/behavior/channel/VoiceChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/VoiceChannelBehavior.kt @@ -12,7 +12,7 @@ import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.channel.VoiceChannelModifyBuilder import dev.kord.rest.request.RestRequestException import dev.kord.rest.service.patchVoiceChannel -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -73,7 +73,7 @@ public fun VoiceChannelBehavior( override val kord: Kord = kord override val supplier: EntitySupplier = strategy.supply(kord) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/channel/threads/ThreadChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/threads/ThreadChannelBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/channel/threads/ThreadChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/threads/ThreadChannelBehavior.kt diff --git a/core/src/main/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt b/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt similarity index 98% rename from core/src/main/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt rename to core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt index 75914d7e7a7a..32d1c4e4a693 100644 --- a/core/src/main/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt +++ b/core/src/commonMain/kotlin/behavior/channel/threads/ThreadParentChannelBehavior.kt @@ -19,7 +19,7 @@ import dev.kord.rest.builder.channel.thread.StartThreadBuilder import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.filter import kotlinx.datetime.Instant -import java.util.* +import dev.kord.core.hash /** * Behavior of channels that can contain public threads. @@ -169,7 +169,7 @@ internal fun ThreadParentChannelBehavior( override val supplier: EntitySupplier get() = supplier - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId @@ -201,7 +201,7 @@ internal fun PrivateThreadParentChannelBehavior( override val supplier: EntitySupplier get() = supplier - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/behavior/interaction/ActionInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/ActionInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/ActionInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/ActionInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/ApplicationCommandInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/ApplicationCommandInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/ApplicationCommandInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/ApplicationCommandInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/AutoCompleteInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/AutoCompleteInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/AutoCompleteInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/AutoCompleteInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/ComponentInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/ComponentInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/ComponentInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/ComponentInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/DataInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/DataInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/DataInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/DataInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/GlobalInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/GlobalInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/GlobalInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/GlobalInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/GuildInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/GuildInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/GuildInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/GuildInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/InteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/InteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/InteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/ModalParentInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/ModalParentInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/ModalParentInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/ModalParentInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/followup/EphemeralFollowupMessageBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/followup/EphemeralFollowupMessageBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/followup/EphemeralFollowupMessageBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/followup/EphemeralFollowupMessageBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/followup/FollowupMessageBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/followup/FollowupMessageBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/followup/FollowupMessageBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/followup/FollowupMessageBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/followup/PublicFollowupMessageBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/followup/PublicFollowupMessageBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/followup/PublicFollowupMessageBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/followup/PublicFollowupMessageBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/DeferredEphemeralMessageInteractionBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/DeferredEphemeralMessageInteractionBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/DeferredEphemeralMessageInteractionBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/DeferredEphemeralMessageInteractionBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/DeferredMessageInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/DeferredMessageInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/DeferredMessageInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/DeferredMessageInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/DeferredPublicMessageInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/DeferredPublicMessageInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/DeferredPublicMessageInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/DeferredPublicMessageInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/EditOriginalResponse.kt b/core/src/commonMain/kotlin/behavior/interaction/response/EditOriginalResponse.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/EditOriginalResponse.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/EditOriginalResponse.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/EphemeralInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/EphemeralInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/EphemeralInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/EphemeralInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/EphemeralMessageInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/EphemeralMessageInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/EphemeralMessageInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/EphemeralMessageInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/FollowupPermittingInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/FollowupPermittingInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/FollowupPermittingInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/FollowupPermittingInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/InteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/InteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/InteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/InteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/MessageInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/MessageInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/MessageInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/MessageInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/PopupInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/PopupInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/PopupInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/PopupInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/PublicInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/PublicInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/PublicInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/PublicInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/behavior/interaction/response/PublicMesageInteractionResponseBehavior.kt b/core/src/commonMain/kotlin/behavior/interaction/response/PublicMesageInteractionResponseBehavior.kt similarity index 100% rename from core/src/main/kotlin/behavior/interaction/response/PublicMesageInteractionResponseBehavior.kt rename to core/src/commonMain/kotlin/behavior/interaction/response/PublicMesageInteractionResponseBehavior.kt diff --git a/core/src/main/kotlin/builder/component/ButtonBuilderExtensions.kt b/core/src/commonMain/kotlin/builder/component/ButtonBuilderExtensions.kt similarity index 100% rename from core/src/main/kotlin/builder/component/ButtonBuilderExtensions.kt rename to core/src/commonMain/kotlin/builder/component/ButtonBuilderExtensions.kt diff --git a/core/src/main/kotlin/builder/kord/KordBuilder.kt b/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt similarity index 95% rename from core/src/main/kotlin/builder/kord/KordBuilder.kt rename to core/src/commonMain/kotlin/builder/kord/KordBuilder.kt index e55b0832da46..a30efa507e99 100644 --- a/core/src/main/kotlin/builder/kord/KordBuilder.kt +++ b/core/src/commonMain/kotlin/builder/kord/KordBuilder.kt @@ -36,11 +36,9 @@ import io.ktor.http.HttpHeaders.UserAgent import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow -import kotlinx.coroutines.runBlocking import kotlinx.serialization.json.Json import mu.KotlinLogging import kotlin.DeprecationLevel.HIDDEN -import kotlin.concurrent.thread import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.time.Duration.Companion.seconds @@ -64,7 +62,9 @@ public operator fun DefaultGateway.Companion.invoke( private val logger = KotlinLogging.logger { } private val gatewayInfoJson = Json { ignoreUnknownKeys = true } -public class KordBuilder(public val token: String) { +public expect class KordBuilder(token: String) : BaseKordBuilder + +public abstract class BaseKordBuilder internal constructor(public val token: String) { private var shardsBuilder: (recommended: Int) -> Shards = { Shards(it) } private var gatewayBuilder: (resources: ClientResources, shards: List) -> List = { resources, shards -> @@ -92,11 +92,6 @@ public class KordBuilder(public val token: String) { */ public var stackTraceRecovery: Boolean = false - /** - * Enable adding a [Runtime.addShutdownHook] to log out of the [Gateway] when the process is killed. - */ - public var enableShutdownHook: Boolean = true - /** * The event flow used by [Kord.eventFlow] to publish [events][Kord.events]. * @@ -236,7 +231,9 @@ public class KordBuilder(public val token: String) { /** * @throws KordInitializationException if something went wrong while getting the bot's gateway information. */ - public suspend fun build(): Kord { + public open suspend fun build(): Kord = buildBase() + + protected suspend fun buildBase(): Kord { val client = httpClient.configure() val gatewayInfo = client.getGatewayInfo() @@ -289,14 +286,6 @@ public class KordBuilder(public val token: String) { val self = getBotIdFromToken(token) - if (enableShutdownHook) { - Runtime.getRuntime().addShutdownHook(thread(false) { - runBlocking { - gateway.detachAll() - } - }) - } - return Kord( resources = resources, cache = cache, diff --git a/core/src/main/kotlin/builder/kord/KordBuilderUtil.kt b/core/src/commonMain/kotlin/builder/kord/KordBuilderUtil.kt similarity index 77% rename from core/src/main/kotlin/builder/kord/KordBuilderUtil.kt rename to core/src/commonMain/kotlin/builder/kord/KordBuilderUtil.kt index cc957bcbfd36..0f0d9e0dd757 100644 --- a/core/src/main/kotlin/builder/kord/KordBuilderUtil.kt +++ b/core/src/commonMain/kotlin/builder/kord/KordBuilderUtil.kt @@ -1,9 +1,9 @@ package dev.kord.core.builder.kord +import dev.kord.common.annotation.KordInternal import dev.kord.common.entity.Snowflake +import dev.kord.common.http.HttpEngine import io.ktor.client.* -import io.ktor.client.engine.cio.* -import io.ktor.client.plugins.* import io.ktor.client.plugins.contentnegotiation.* import io.ktor.client.plugins.websocket.* import io.ktor.serialization.kotlinx.json.* @@ -19,7 +19,9 @@ internal fun HttpClientConfig<*>.defaultConfig() { install(WebSockets) } -internal fun HttpClient?.configure(): HttpClient { +/** @suppress */ +@KordInternal +public fun HttpClient?.configure(): HttpClient { if (this != null) return this.config { defaultConfig() } @@ -31,7 +33,7 @@ internal fun HttpClient?.configure(): HttpClient { isLenient = true } - return HttpClient(CIO) { + return HttpClient(HttpEngine) { defaultConfig() install(ContentNegotiation) { json(json) @@ -39,8 +41,9 @@ internal fun HttpClient?.configure(): HttpClient { } } - -internal fun getBotIdFromToken(token: String) = try { +/** @suppress */ +@KordInternal +public fun getBotIdFromToken(token: String): Snowflake = try { Snowflake(token.substringBefore('.').decodeBase64String()) } catch (exception: IllegalArgumentException) { throw IllegalArgumentException("Malformed bot token: '$token'. Make sure that your token is correct.") diff --git a/core/src/main/kotlin/builder/kord/KordProxyBuilder.kt b/core/src/commonMain/kotlin/builder/kord/KordProxyBuilder.kt similarity index 100% rename from core/src/main/kotlin/builder/kord/KordProxyBuilder.kt rename to core/src/commonMain/kotlin/builder/kord/KordProxyBuilder.kt diff --git a/core/src/main/kotlin/builder/kord/KordRestOnlyBuilder.kt b/core/src/commonMain/kotlin/builder/kord/KordRestOnlyBuilder.kt similarity index 100% rename from core/src/main/kotlin/builder/kord/KordRestOnlyBuilder.kt rename to core/src/commonMain/kotlin/builder/kord/KordRestOnlyBuilder.kt diff --git a/core/src/main/kotlin/builder/kord/RestOnlyBuilder.kt b/core/src/commonMain/kotlin/builder/kord/RestOnlyBuilder.kt similarity index 100% rename from core/src/main/kotlin/builder/kord/RestOnlyBuilder.kt rename to core/src/commonMain/kotlin/builder/kord/RestOnlyBuilder.kt diff --git a/core/src/main/kotlin/cache/CachingGateway.kt b/core/src/commonMain/kotlin/cache/CachingGateway.kt similarity index 100% rename from core/src/main/kotlin/cache/CachingGateway.kt rename to core/src/commonMain/kotlin/cache/CachingGateway.kt diff --git a/core/src/main/kotlin/cache/DataCacheExtensions.kt b/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt similarity index 91% rename from core/src/main/kotlin/cache/DataCacheExtensions.kt rename to core/src/commonMain/kotlin/cache/DataCacheExtensions.kt index 0ebc3deba6a5..ec322be7f50d 100644 --- a/core/src/main/kotlin/cache/DataCacheExtensions.kt +++ b/core/src/commonMain/kotlin/cache/DataCacheExtensions.kt @@ -2,12 +2,16 @@ package dev.kord.core.cache import dev.kord.cache.api.DataCache import dev.kord.cache.api.query +import dev.kord.common.annotation.KordInternal import dev.kord.core.cache.data.* /** * Registers all Kord data classes for this cache + * + * @suppress */ -internal suspend fun DataCache.registerKordData() = register( +@KordInternal +public suspend fun DataCache.registerKordData(): Unit = register( RoleData.description, ChannelData.description, GuildData.description, diff --git a/core/src/main/kotlin/cache/DataCacheView.kt b/core/src/commonMain/kotlin/cache/DataCacheView.kt similarity index 100% rename from core/src/main/kotlin/cache/DataCacheView.kt rename to core/src/commonMain/kotlin/cache/DataCacheView.kt diff --git a/core/src/main/kotlin/cache/KordCache.kt b/core/src/commonMain/kotlin/cache/KordCache.kt similarity index 90% rename from core/src/main/kotlin/cache/KordCache.kt rename to core/src/commonMain/kotlin/cache/KordCache.kt index c886b88d1713..e0e304d7ec99 100644 --- a/core/src/main/kotlin/cache/KordCache.kt +++ b/core/src/commonMain/kotlin/cache/KordCache.kt @@ -7,10 +7,9 @@ import dev.kord.cache.api.delegate.DelegatingDataCache import dev.kord.cache.api.delegate.EntrySupplier import dev.kord.cache.map.MapLikeCollection import dev.kord.cache.map.internal.MapEntryCache -import dev.kord.cache.map.lruLinkedHashMap +import dev.kord.common.ConcurrentHashMap import dev.kord.common.entity.Snowflake import dev.kord.core.cache.data.* -import java.util.concurrent.ConcurrentHashMap public typealias Generator = (cache: DataCache, description: DataDescription) -> DataEntryCache @@ -20,7 +19,7 @@ public class KordCacheBuilder { * The default behavior for all types not explicitly configured, by default a [ConcurrentHashMap] is supplied. */ public var defaultGenerator: Generator = { cache, description -> - MapEntryCache(cache, description, MapLikeCollection.concurrentHashMap()) + MapEntryCache(cache, description, MapLikeCollection.concurrentHashMap()) } private val descriptionGenerators: MutableMap, Generator<*, *>> = mutableMapOf() @@ -42,14 +41,6 @@ public class KordCacheBuilder { */ public fun none(): Generator = { _, _ -> DataEntryCache.none() } - /** - * A Generator creating [DataEntryCaches][DataEntryCache] with a maximum [size], removing items on last insertion. - * Shortcut for [lruLinkedHashMap]. - */ - public fun lruCache(size: Int = 100): Generator = { cache, description -> - MapEntryCache(cache, description, MapLikeCollection.lruLinkedHashMap(size)) - } - @Suppress("UNCHECKED_CAST") public fun forDescription(description: DataDescription, generator: Generator?) { if (generator == null) return run { diff --git a/core/src/main/kotlin/cache/Query.kt b/core/src/commonMain/kotlin/cache/Query.kt similarity index 98% rename from core/src/main/kotlin/cache/Query.kt rename to core/src/commonMain/kotlin/cache/Query.kt index 43328bc17884..4a68a89b2966 100644 --- a/core/src/main/kotlin/cache/Query.kt +++ b/core/src/commonMain/kotlin/cache/Query.kt @@ -5,6 +5,7 @@ import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.Optional import dev.kord.common.entity.optional.OptionalSnowflake import dev.kord.common.entity.optional.optionalSnowflake +import kotlin.jvm.JvmName import kotlin.reflect.KProperty1 public fun QueryBuilder.idEq(property: KProperty1, value: Snowflake?) { diff --git a/core/src/main/kotlin/cache/data/ActivityData.kt b/core/src/commonMain/kotlin/cache/data/ActivityData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ActivityData.kt rename to core/src/commonMain/kotlin/cache/data/ActivityData.kt diff --git a/core/src/main/kotlin/cache/data/ApplicationCommandData.kt b/core/src/commonMain/kotlin/cache/data/ApplicationCommandData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ApplicationCommandData.kt rename to core/src/commonMain/kotlin/cache/data/ApplicationCommandData.kt diff --git a/core/src/main/kotlin/cache/data/ApplicationData.kt b/core/src/commonMain/kotlin/cache/data/ApplicationData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ApplicationData.kt rename to core/src/commonMain/kotlin/cache/data/ApplicationData.kt diff --git a/core/src/main/kotlin/cache/data/AttachmentData.kt b/core/src/commonMain/kotlin/cache/data/AttachmentData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/AttachmentData.kt rename to core/src/commonMain/kotlin/cache/data/AttachmentData.kt diff --git a/core/src/main/kotlin/cache/data/AutoModeration.kt b/core/src/commonMain/kotlin/cache/data/AutoModeration.kt similarity index 100% rename from core/src/main/kotlin/cache/data/AutoModeration.kt rename to core/src/commonMain/kotlin/cache/data/AutoModeration.kt diff --git a/core/src/main/kotlin/cache/data/BanData.kt b/core/src/commonMain/kotlin/cache/data/BanData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/BanData.kt rename to core/src/commonMain/kotlin/cache/data/BanData.kt diff --git a/core/src/main/kotlin/cache/data/ChannelData.kt b/core/src/commonMain/kotlin/cache/data/ChannelData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ChannelData.kt rename to core/src/commonMain/kotlin/cache/data/ChannelData.kt diff --git a/core/src/main/kotlin/cache/data/ClientStatusData.kt b/core/src/commonMain/kotlin/cache/data/ClientStatusData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ClientStatusData.kt rename to core/src/commonMain/kotlin/cache/data/ClientStatusData.kt diff --git a/core/src/main/kotlin/cache/data/ComponentData.kt b/core/src/commonMain/kotlin/cache/data/ComponentData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ComponentData.kt rename to core/src/commonMain/kotlin/cache/data/ComponentData.kt diff --git a/core/src/main/kotlin/cache/data/EmbedData.kt b/core/src/commonMain/kotlin/cache/data/EmbedData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/EmbedData.kt rename to core/src/commonMain/kotlin/cache/data/EmbedData.kt diff --git a/core/src/main/kotlin/cache/data/EmojiData.kt b/core/src/commonMain/kotlin/cache/data/EmojiData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/EmojiData.kt rename to core/src/commonMain/kotlin/cache/data/EmojiData.kt diff --git a/core/src/main/kotlin/cache/data/GuildApplicationCommandPermissionData.kt b/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildApplicationCommandPermissionData.kt rename to core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionData.kt diff --git a/core/src/main/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt b/core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt rename to core/src/commonMain/kotlin/cache/data/GuildApplicationCommandPermissionsData.kt diff --git a/core/src/main/kotlin/cache/data/GuildData.kt b/core/src/commonMain/kotlin/cache/data/GuildData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildData.kt rename to core/src/commonMain/kotlin/cache/data/GuildData.kt diff --git a/core/src/main/kotlin/cache/data/GuildPreviewData.kt b/core/src/commonMain/kotlin/cache/data/GuildPreviewData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildPreviewData.kt rename to core/src/commonMain/kotlin/cache/data/GuildPreviewData.kt diff --git a/core/src/main/kotlin/cache/data/GuildScheduledEventData.kt b/core/src/commonMain/kotlin/cache/data/GuildScheduledEventData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildScheduledEventData.kt rename to core/src/commonMain/kotlin/cache/data/GuildScheduledEventData.kt diff --git a/core/src/main/kotlin/cache/data/GuildWidgetData.kt b/core/src/commonMain/kotlin/cache/data/GuildWidgetData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/GuildWidgetData.kt rename to core/src/commonMain/kotlin/cache/data/GuildWidgetData.kt diff --git a/core/src/main/kotlin/cache/data/IntegrationData.kt b/core/src/commonMain/kotlin/cache/data/IntegrationData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/IntegrationData.kt rename to core/src/commonMain/kotlin/cache/data/IntegrationData.kt diff --git a/core/src/main/kotlin/cache/data/IntegrationsAccountData.kt b/core/src/commonMain/kotlin/cache/data/IntegrationsAccountData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/IntegrationsAccountData.kt rename to core/src/commonMain/kotlin/cache/data/IntegrationsAccountData.kt diff --git a/core/src/main/kotlin/cache/data/InteractionData.kt b/core/src/commonMain/kotlin/cache/data/InteractionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/InteractionData.kt rename to core/src/commonMain/kotlin/cache/data/InteractionData.kt diff --git a/core/src/main/kotlin/cache/data/InviteCreateData.kt b/core/src/commonMain/kotlin/cache/data/InviteCreateData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/InviteCreateData.kt rename to core/src/commonMain/kotlin/cache/data/InviteCreateData.kt diff --git a/core/src/main/kotlin/cache/data/InviteData.kt b/core/src/commonMain/kotlin/cache/data/InviteData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/InviteData.kt rename to core/src/commonMain/kotlin/cache/data/InviteData.kt diff --git a/core/src/main/kotlin/cache/data/InviteDeleteData.kt b/core/src/commonMain/kotlin/cache/data/InviteDeleteData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/InviteDeleteData.kt rename to core/src/commonMain/kotlin/cache/data/InviteDeleteData.kt diff --git a/core/src/main/kotlin/cache/data/MemberData.kt b/core/src/commonMain/kotlin/cache/data/MemberData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/MemberData.kt rename to core/src/commonMain/kotlin/cache/data/MemberData.kt diff --git a/core/src/main/kotlin/cache/data/MembersChunkData.kt b/core/src/commonMain/kotlin/cache/data/MembersChunkData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/MembersChunkData.kt rename to core/src/commonMain/kotlin/cache/data/MembersChunkData.kt diff --git a/core/src/main/kotlin/cache/data/MessageData.kt b/core/src/commonMain/kotlin/cache/data/MessageData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/MessageData.kt rename to core/src/commonMain/kotlin/cache/data/MessageData.kt diff --git a/core/src/main/kotlin/cache/data/MessageInteractionData.kt b/core/src/commonMain/kotlin/cache/data/MessageInteractionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/MessageInteractionData.kt rename to core/src/commonMain/kotlin/cache/data/MessageInteractionData.kt diff --git a/core/src/main/kotlin/cache/data/MessageReferenceData.kt b/core/src/commonMain/kotlin/cache/data/MessageReferenceData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/MessageReferenceData.kt rename to core/src/commonMain/kotlin/cache/data/MessageReferenceData.kt diff --git a/core/src/main/kotlin/cache/data/PartialGuildData.kt b/core/src/commonMain/kotlin/cache/data/PartialGuildData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/PartialGuildData.kt rename to core/src/commonMain/kotlin/cache/data/PartialGuildData.kt diff --git a/core/src/main/kotlin/cache/data/PermissionOverwriteData.kt b/core/src/commonMain/kotlin/cache/data/PermissionOverwriteData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/PermissionOverwriteData.kt rename to core/src/commonMain/kotlin/cache/data/PermissionOverwriteData.kt diff --git a/core/src/main/kotlin/cache/data/PresenceData.kt b/core/src/commonMain/kotlin/cache/data/PresenceData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/PresenceData.kt rename to core/src/commonMain/kotlin/cache/data/PresenceData.kt diff --git a/core/src/main/kotlin/cache/data/ReactionData.kt b/core/src/commonMain/kotlin/cache/data/ReactionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ReactionData.kt rename to core/src/commonMain/kotlin/cache/data/ReactionData.kt diff --git a/core/src/main/kotlin/cache/data/ReactionRemoveEmojiData.kt b/core/src/commonMain/kotlin/cache/data/ReactionRemoveEmojiData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ReactionRemoveEmojiData.kt rename to core/src/commonMain/kotlin/cache/data/ReactionRemoveEmojiData.kt diff --git a/core/src/main/kotlin/cache/data/RegionData.kt b/core/src/commonMain/kotlin/cache/data/RegionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/RegionData.kt rename to core/src/commonMain/kotlin/cache/data/RegionData.kt diff --git a/core/src/main/kotlin/cache/data/RoleData.kt b/core/src/commonMain/kotlin/cache/data/RoleData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/RoleData.kt rename to core/src/commonMain/kotlin/cache/data/RoleData.kt diff --git a/core/src/main/kotlin/cache/data/RoleTagsData.kt b/core/src/commonMain/kotlin/cache/data/RoleTagsData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/RoleTagsData.kt rename to core/src/commonMain/kotlin/cache/data/RoleTagsData.kt diff --git a/core/src/main/kotlin/cache/data/SelectOptionData.kt b/core/src/commonMain/kotlin/cache/data/SelectOptionData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/SelectOptionData.kt rename to core/src/commonMain/kotlin/cache/data/SelectOptionData.kt diff --git a/core/src/main/kotlin/cache/data/StageInstanceData.kt b/core/src/commonMain/kotlin/cache/data/StageInstanceData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/StageInstanceData.kt rename to core/src/commonMain/kotlin/cache/data/StageInstanceData.kt diff --git a/core/src/main/kotlin/cache/data/StickerData.kt b/core/src/commonMain/kotlin/cache/data/StickerData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/StickerData.kt rename to core/src/commonMain/kotlin/cache/data/StickerData.kt diff --git a/core/src/main/kotlin/cache/data/TeamData.kt b/core/src/commonMain/kotlin/cache/data/TeamData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/TeamData.kt rename to core/src/commonMain/kotlin/cache/data/TeamData.kt diff --git a/core/src/main/kotlin/cache/data/TemplateData.kt b/core/src/commonMain/kotlin/cache/data/TemplateData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/TemplateData.kt rename to core/src/commonMain/kotlin/cache/data/TemplateData.kt diff --git a/core/src/main/kotlin/cache/data/ThreadListSyncData.kt b/core/src/commonMain/kotlin/cache/data/ThreadListSyncData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ThreadListSyncData.kt rename to core/src/commonMain/kotlin/cache/data/ThreadListSyncData.kt diff --git a/core/src/main/kotlin/cache/data/ThreadMemberData.kt b/core/src/commonMain/kotlin/cache/data/ThreadMemberData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ThreadMemberData.kt rename to core/src/commonMain/kotlin/cache/data/ThreadMemberData.kt diff --git a/core/src/main/kotlin/cache/data/ThreadMembersUpdateEventData.kt b/core/src/commonMain/kotlin/cache/data/ThreadMembersUpdateEventData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/ThreadMembersUpdateEventData.kt rename to core/src/commonMain/kotlin/cache/data/ThreadMembersUpdateEventData.kt diff --git a/core/src/main/kotlin/cache/data/UserData.kt b/core/src/commonMain/kotlin/cache/data/UserData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/UserData.kt rename to core/src/commonMain/kotlin/cache/data/UserData.kt diff --git a/core/src/main/kotlin/cache/data/VoiceStateData.kt b/core/src/commonMain/kotlin/cache/data/VoiceStateData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/VoiceStateData.kt rename to core/src/commonMain/kotlin/cache/data/VoiceStateData.kt diff --git a/core/src/main/kotlin/cache/data/WebhookData.kt b/core/src/commonMain/kotlin/cache/data/WebhookData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/WebhookData.kt rename to core/src/commonMain/kotlin/cache/data/WebhookData.kt diff --git a/core/src/main/kotlin/cache/data/WelcomeScreenData.kt b/core/src/commonMain/kotlin/cache/data/WelcomeScreenData.kt similarity index 100% rename from core/src/main/kotlin/cache/data/WelcomeScreenData.kt rename to core/src/commonMain/kotlin/cache/data/WelcomeScreenData.kt diff --git a/core/src/main/kotlin/entity/Activity.kt b/core/src/commonMain/kotlin/entity/Activity.kt similarity index 100% rename from core/src/main/kotlin/entity/Activity.kt rename to core/src/commonMain/kotlin/entity/Activity.kt diff --git a/core/src/main/kotlin/entity/Application.kt b/core/src/commonMain/kotlin/entity/Application.kt similarity index 98% rename from core/src/main/kotlin/entity/Application.kt rename to core/src/commonMain/kotlin/entity/Application.kt index 61deac4406c3..f00c41bd06e4 100644 --- a/core/src/main/kotlin/entity/Application.kt +++ b/core/src/commonMain/kotlin/entity/Application.kt @@ -13,7 +13,7 @@ import dev.kord.core.cache.data.PartialApplicationData import dev.kord.core.event.guild.InviteCreateEvent import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.Objects +import dev.kord.core.hash public sealed class BaseApplication( final override val kord: Kord, @@ -74,7 +74,7 @@ public sealed class BaseApplication( abstract override fun withStrategy(strategy: EntitySupplyStrategy<*>): BaseApplication - final override fun hashCode(): Int = Objects.hash(id) + final override fun hashCode(): Int = hash(id) final override fun equals(other: Any?): Boolean = other is BaseApplication && this.id == other.id } diff --git a/core/src/main/kotlin/entity/Attachment.kt b/core/src/commonMain/kotlin/entity/Attachment.kt similarity index 96% rename from core/src/main/kotlin/entity/Attachment.kt rename to core/src/commonMain/kotlin/entity/Attachment.kt index 926a917b9376..6bd5b83254cc 100644 --- a/core/src/main/kotlin/entity/Attachment.kt +++ b/core/src/commonMain/kotlin/entity/Attachment.kt @@ -6,7 +6,7 @@ import dev.kord.common.entity.optional.value import dev.kord.core.Kord import dev.kord.core.cache.data.AttachmentData import dev.kord.rest.Image -import java.util.* +import dev.kord.core.hash /** * An instance of a [Discord Attachment](https://discord.com/developers/docs/resources/channel#attachment-object). @@ -69,7 +69,7 @@ public data class Attachment(val data: AttachmentData, override val kord: Kord) */ val isImage: Boolean get() = Image.Format.isSupported(filename) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is Attachment -> other.id == id diff --git a/core/src/main/kotlin/entity/AuditLog.kt b/core/src/commonMain/kotlin/entity/AuditLog.kt similarity index 100% rename from core/src/main/kotlin/entity/AuditLog.kt rename to core/src/commonMain/kotlin/entity/AuditLog.kt diff --git a/core/src/main/kotlin/entity/Ban.kt b/core/src/commonMain/kotlin/entity/Ban.kt similarity index 100% rename from core/src/main/kotlin/entity/Ban.kt rename to core/src/commonMain/kotlin/entity/Ban.kt diff --git a/core/src/main/kotlin/entity/Embed.kt b/core/src/commonMain/kotlin/entity/Embed.kt similarity index 100% rename from core/src/main/kotlin/entity/Embed.kt rename to core/src/commonMain/kotlin/entity/Embed.kt diff --git a/core/src/main/kotlin/entity/Emoji.kt b/core/src/commonMain/kotlin/entity/Emoji.kt similarity index 98% rename from core/src/main/kotlin/entity/Emoji.kt rename to core/src/commonMain/kotlin/entity/Emoji.kt index e7e04d32d359..c7f33ff8d815 100644 --- a/core/src/main/kotlin/entity/Emoji.kt +++ b/core/src/commonMain/kotlin/entity/Emoji.kt @@ -14,7 +14,7 @@ import dev.kord.rest.builder.guild.EmojiModifyBuilder import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filter -import java.util.* +import dev.kord.core.hash import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -180,7 +180,7 @@ public class GuildEmoji( */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): GuildEmoji = GuildEmoji(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildEmoji -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/Entity.kt b/core/src/commonMain/kotlin/entity/Entity.kt similarity index 95% rename from core/src/main/kotlin/entity/Entity.kt rename to core/src/commonMain/kotlin/entity/Entity.kt index 55c5007281db..592c39cfb15d 100644 --- a/core/src/main/kotlin/entity/Entity.kt +++ b/core/src/commonMain/kotlin/entity/Entity.kt @@ -2,7 +2,6 @@ package dev.kord.core.entity import dev.kord.common.entity.Snowflake import dev.kord.core.KordObject -import java.util.Comparator public interface Entity : Comparable { /** diff --git a/core/src/main/kotlin/entity/Guild.kt b/core/src/commonMain/kotlin/entity/Guild.kt similarity index 98% rename from core/src/main/kotlin/entity/Guild.kt rename to core/src/commonMain/kotlin/entity/Guild.kt index 34aaf1144db2..d5ff19fba80a 100644 --- a/core/src/main/kotlin/entity/Guild.kt +++ b/core/src/commonMain/kotlin/entity/Guild.kt @@ -1,5 +1,6 @@ package dev.kord.core.entity +import dev.kord.common.Locale import dev.kord.common.entity.* import dev.kord.common.entity.optional.* import dev.kord.common.exception.RequestException @@ -23,7 +24,7 @@ import dev.kord.rest.service.RestClient import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.datetime.Instant -import java.util.* +import dev.kord.core.hash import kotlin.time.Duration /** @@ -214,7 +215,7 @@ public class Guild( TopGuildMessageChannelBehavior(guildId = id, id = it, kord = kord) } - public val preferredLocale: Locale get() = Locale.forLanguageTag(data.preferredLocale) + public val preferredLocale: Locale get() = Locale.fromString(data.preferredLocale) /** * The behaviors of all [channels][TopGuildChannel]. @@ -502,7 +503,7 @@ public class Guild( */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): Guild = Guild(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is GuildBehavior -> other.id == id diff --git a/core/src/main/kotlin/entity/GuildOnboarding.kt b/core/src/commonMain/kotlin/entity/GuildOnboarding.kt similarity index 98% rename from core/src/main/kotlin/entity/GuildOnboarding.kt rename to core/src/commonMain/kotlin/entity/GuildOnboarding.kt index f30aad2e0883..089124d25c73 100644 --- a/core/src/main/kotlin/entity/GuildOnboarding.kt +++ b/core/src/commonMain/kotlin/entity/GuildOnboarding.kt @@ -10,12 +10,12 @@ import dev.kord.core.behavior.channel.TopGuildChannelBehavior import dev.kord.core.cache.data.toData import dev.kord.core.entity.channel.TopGuildChannel import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.filter -import java.util.* /** * Represents the [onboarding](https://support.discord.com/hc/en-us/articles/11074987197975-Community-Onboarding-FAQ) @@ -114,7 +114,7 @@ public class GuildOnboarding( override fun equals(other: Any?): Boolean = other is Prompt && this.id == other.id && this.guildId == other.guildId - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun toString(): String = "GuildOnboarding.Prompt(data=$data, guildId=$guildId, kord=$kord)" @@ -197,7 +197,7 @@ public class GuildOnboarding( override fun equals(other: Any?): Boolean = other is Option && this.id == other.id && this.guildId == other.guildId - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun toString(): String = "GuildOnboarding.Prompt.Option(data=$data, guildId=$guildId, kord=$kord, supplier=$supplier)" } diff --git a/core/src/main/kotlin/entity/GuildPreview.kt b/core/src/commonMain/kotlin/entity/GuildPreview.kt similarity index 100% rename from core/src/main/kotlin/entity/GuildPreview.kt rename to core/src/commonMain/kotlin/entity/GuildPreview.kt diff --git a/core/src/main/kotlin/entity/GuildScheduledEvent.kt b/core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt similarity index 100% rename from core/src/main/kotlin/entity/GuildScheduledEvent.kt rename to core/src/commonMain/kotlin/entity/GuildScheduledEvent.kt diff --git a/core/src/main/kotlin/entity/GuildWidget.kt b/core/src/commonMain/kotlin/entity/GuildWidget.kt similarity index 100% rename from core/src/main/kotlin/entity/GuildWidget.kt rename to core/src/commonMain/kotlin/entity/GuildWidget.kt diff --git a/core/src/main/kotlin/entity/Icon.kt b/core/src/commonMain/kotlin/entity/Icon.kt similarity index 95% rename from core/src/main/kotlin/entity/Icon.kt rename to core/src/commonMain/kotlin/entity/Icon.kt index cfc623174ed1..77020b2f91e6 100644 --- a/core/src/main/kotlin/entity/Icon.kt +++ b/core/src/commonMain/kotlin/entity/Icon.kt @@ -37,7 +37,7 @@ public sealed class Icon( }) override fun toString(): String { - return "Icon(type=${javaClass.name},format=$format,animated=$animated,cdnUrl=$cdnUrl,kord=$kord)" + return "Icon(type=${this::class.simpleName},format=$format,animated=$animated,cdnUrl=$cdnUrl,kord=$kord)" } public class EmojiIcon(animated: Boolean, emojiId: Snowflake, kord: Kord) : diff --git a/core/src/main/kotlin/entity/Integration.kt b/core/src/commonMain/kotlin/entity/Integration.kt similarity index 96% rename from core/src/main/kotlin/entity/Integration.kt rename to core/src/commonMain/kotlin/entity/Integration.kt index 8facaf2cc94b..182b8a6fe803 100644 --- a/core/src/main/kotlin/entity/Integration.kt +++ b/core/src/commonMain/kotlin/entity/Integration.kt @@ -10,15 +10,17 @@ import dev.kord.core.behavior.RoleBehavior import dev.kord.core.behavior.UserBehavior import dev.kord.core.cache.data.IntegrationData import dev.kord.core.exception.EntityNotFoundException +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.builder.integration.IntegrationModifyBuilder import dev.kord.rest.request.RestRequestException import kotlinx.datetime.Instant -import java.util.* import kotlin.DeprecationLevel.HIDDEN import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.js.JsName +import kotlin.jvm.JvmName import kotlin.time.Duration /** @@ -52,6 +54,7 @@ public class Integration( get() = data.enabled @Deprecated("Binary compatibility, was non-nullable before. Keep for some releases.", level = HIDDEN) + @JsName("_isSyncing") // binary compatibility with js doesn't matter as this is the first JS release public fun isSyncing(): Boolean = isSyncing!! /** @@ -171,7 +174,7 @@ public class Integration( override fun withStrategy(strategy: EntitySupplyStrategy<*>): Integration = Integration(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is Integration -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/Invite.kt b/core/src/commonMain/kotlin/entity/Invite.kt similarity index 100% rename from core/src/main/kotlin/entity/Invite.kt rename to core/src/commonMain/kotlin/entity/Invite.kt diff --git a/core/src/main/kotlin/entity/Member.kt b/core/src/commonMain/kotlin/entity/Member.kt similarity index 98% rename from core/src/main/kotlin/entity/Member.kt rename to core/src/commonMain/kotlin/entity/Member.kt index 511a4f73f9a1..ac86987ee908 100644 --- a/core/src/main/kotlin/entity/Member.kt +++ b/core/src/commonMain/kotlin/entity/Member.kt @@ -14,7 +14,7 @@ import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import kotlinx.coroutines.flow.* import kotlinx.datetime.Instant -import java.util.* +import dev.kord.core.hash /** * An instance of a [Discord Member](https://discord.com/developers/docs/resources/guild#guild-member-object). @@ -134,7 +134,7 @@ public class Member( override suspend fun asMemberOrNull(): Member = this - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is MemberBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/Message.kt b/core/src/commonMain/kotlin/entity/Message.kt similarity index 99% rename from core/src/main/kotlin/entity/Message.kt rename to core/src/commonMain/kotlin/entity/Message.kt index bd2a7cba89ba..e193aaf835fd 100644 --- a/core/src/main/kotlin/entity/Message.kt +++ b/core/src/commonMain/kotlin/entity/Message.kt @@ -29,7 +29,7 @@ import dev.kord.core.supplier.getChannelOf import dev.kord.core.supplier.getChannelOfOrNull import kotlinx.coroutines.flow.* import kotlinx.datetime.Instant -import java.util.Objects +import dev.kord.core.hash /** * An instance of a [Discord Message][https://discord.com/developers/docs/resources/channel#message-object]. @@ -367,7 +367,7 @@ public class Message( */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): Message = Message(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is MessageBehavior -> other.id == id && other.channelId == channelId diff --git a/core/src/main/kotlin/entity/MessageReference.kt b/core/src/commonMain/kotlin/entity/MessageReference.kt similarity index 100% rename from core/src/main/kotlin/entity/MessageReference.kt rename to core/src/commonMain/kotlin/entity/MessageReference.kt diff --git a/core/src/main/kotlin/entity/PartialGuild.kt b/core/src/commonMain/kotlin/entity/PartialGuild.kt similarity index 98% rename from core/src/main/kotlin/entity/PartialGuild.kt rename to core/src/commonMain/kotlin/entity/PartialGuild.kt index 24d960e7d288..9f7220cdac90 100644 --- a/core/src/main/kotlin/entity/PartialGuild.kt +++ b/core/src/commonMain/kotlin/entity/PartialGuild.kt @@ -15,7 +15,7 @@ import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.rest.Image import dev.kord.rest.service.RestClient -import java.util.* +import dev.kord.core.hash public class PartialGuild( public val data: PartialGuildData, @@ -154,7 +154,7 @@ public class PartialGuild( public suspend fun getGuildOrNull(): Guild? = supplier.getGuildOrNull(id) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is GuildBehavior -> other.id == id diff --git a/core/src/main/kotlin/entity/PermissionOverwrite.kt b/core/src/commonMain/kotlin/entity/PermissionOverwrite.kt similarity index 100% rename from core/src/main/kotlin/entity/PermissionOverwrite.kt rename to core/src/commonMain/kotlin/entity/PermissionOverwrite.kt diff --git a/core/src/main/kotlin/entity/PermissionOverwriteEntity.kt b/core/src/commonMain/kotlin/entity/PermissionOverwriteEntity.kt similarity index 100% rename from core/src/main/kotlin/entity/PermissionOverwriteEntity.kt rename to core/src/commonMain/kotlin/entity/PermissionOverwriteEntity.kt diff --git a/core/src/main/kotlin/entity/Presence.kt b/core/src/commonMain/kotlin/entity/Presence.kt similarity index 100% rename from core/src/main/kotlin/entity/Presence.kt rename to core/src/commonMain/kotlin/entity/Presence.kt diff --git a/core/src/main/kotlin/entity/Reaction.kt b/core/src/commonMain/kotlin/entity/Reaction.kt similarity index 100% rename from core/src/main/kotlin/entity/Reaction.kt rename to core/src/commonMain/kotlin/entity/Reaction.kt diff --git a/core/src/main/kotlin/entity/ReactionEmoji.kt b/core/src/commonMain/kotlin/entity/ReactionEmoji.kt similarity index 100% rename from core/src/main/kotlin/entity/ReactionEmoji.kt rename to core/src/commonMain/kotlin/entity/ReactionEmoji.kt diff --git a/core/src/main/kotlin/entity/Region.kt b/core/src/commonMain/kotlin/entity/Region.kt similarity index 90% rename from core/src/main/kotlin/entity/Region.kt rename to core/src/commonMain/kotlin/entity/Region.kt index 26c9b4334dcd..e6ff8acd7472 100644 --- a/core/src/main/kotlin/entity/Region.kt +++ b/core/src/commonMain/kotlin/entity/Region.kt @@ -3,7 +3,7 @@ package dev.kord.core.entity import dev.kord.core.Kord import dev.kord.core.KordObject import dev.kord.core.cache.data.RegionData -import java.util.* +import dev.kord.core.hash public class Region(public val data: RegionData, override val kord: Kord) : KordObject { public val id: String @@ -17,7 +17,7 @@ public class Region(public val data: RegionData, override val kord: Kord) : Kord public val isOptimal: Boolean get() = data.optimal - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is Region -> other.id == id diff --git a/core/src/main/kotlin/entity/Role.kt b/core/src/commonMain/kotlin/entity/Role.kt similarity index 96% rename from core/src/main/kotlin/entity/Role.kt rename to core/src/commonMain/kotlin/entity/Role.kt index c2ccede750ec..88408436f480 100644 --- a/core/src/main/kotlin/entity/Role.kt +++ b/core/src/commonMain/kotlin/entity/Role.kt @@ -9,7 +9,7 @@ import dev.kord.core.behavior.RoleBehavior import dev.kord.core.cache.data.RoleData import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash public data class Role( val data: RoleData, @@ -60,7 +60,7 @@ public data class Role( */ override fun withStrategy(strategy: EntitySupplyStrategy<*>): Role = Role(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is RoleBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/RoleTags.kt b/core/src/commonMain/kotlin/entity/RoleTags.kt similarity index 100% rename from core/src/main/kotlin/entity/RoleTags.kt rename to core/src/commonMain/kotlin/entity/RoleTags.kt diff --git a/core/src/main/kotlin/entity/StageInstance.kt b/core/src/commonMain/kotlin/entity/StageInstance.kt similarity index 100% rename from core/src/main/kotlin/entity/StageInstance.kt rename to core/src/commonMain/kotlin/entity/StageInstance.kt diff --git a/core/src/main/kotlin/entity/Sticker.kt b/core/src/commonMain/kotlin/entity/Sticker.kt similarity index 100% rename from core/src/main/kotlin/entity/Sticker.kt rename to core/src/commonMain/kotlin/entity/Sticker.kt diff --git a/core/src/main/kotlin/entity/Strategizable.kt b/core/src/commonMain/kotlin/entity/Strategizable.kt similarity index 100% rename from core/src/main/kotlin/entity/Strategizable.kt rename to core/src/commonMain/kotlin/entity/Strategizable.kt diff --git a/core/src/main/kotlin/entity/Team.kt b/core/src/commonMain/kotlin/entity/Team.kt similarity index 100% rename from core/src/main/kotlin/entity/Team.kt rename to core/src/commonMain/kotlin/entity/Team.kt diff --git a/core/src/main/kotlin/entity/Template.kt b/core/src/commonMain/kotlin/entity/Template.kt similarity index 100% rename from core/src/main/kotlin/entity/Template.kt rename to core/src/commonMain/kotlin/entity/Template.kt diff --git a/core/src/main/kotlin/entity/User.kt b/core/src/commonMain/kotlin/entity/User.kt similarity index 100% rename from core/src/main/kotlin/entity/User.kt rename to core/src/commonMain/kotlin/entity/User.kt diff --git a/core/src/main/kotlin/entity/VoiceState.kt b/core/src/commonMain/kotlin/entity/VoiceState.kt similarity index 100% rename from core/src/main/kotlin/entity/VoiceState.kt rename to core/src/commonMain/kotlin/entity/VoiceState.kt diff --git a/core/src/main/kotlin/entity/Webhook.kt b/core/src/commonMain/kotlin/entity/Webhook.kt similarity index 97% rename from core/src/main/kotlin/entity/Webhook.kt rename to core/src/commonMain/kotlin/entity/Webhook.kt index 64ae09d499e2..2874331d5050 100644 --- a/core/src/main/kotlin/entity/Webhook.kt +++ b/core/src/commonMain/kotlin/entity/Webhook.kt @@ -15,7 +15,7 @@ import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.core.supplier.getChannelOf import dev.kord.core.supplier.getChannelOfOrNull -import java.util.Objects +import dev.kord.core.hash public data class Webhook( val data: WebhookData, @@ -72,7 +72,7 @@ public data class Webhook( override fun withStrategy(strategy: EntitySupplyStrategy<*>): Webhook = Webhook(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is WebhookBehavior -> other.id == id diff --git a/core/src/main/kotlin/entity/WelcomeScreen.kt b/core/src/commonMain/kotlin/entity/WelcomeScreen.kt similarity index 100% rename from core/src/main/kotlin/entity/WelcomeScreen.kt rename to core/src/commonMain/kotlin/entity/WelcomeScreen.kt diff --git a/core/src/main/kotlin/entity/application/ApplicationCommand.kt b/core/src/commonMain/kotlin/entity/application/ApplicationCommand.kt similarity index 100% rename from core/src/main/kotlin/entity/application/ApplicationCommand.kt rename to core/src/commonMain/kotlin/entity/application/ApplicationCommand.kt diff --git a/core/src/main/kotlin/entity/application/ApplicationGuildCommandPermissions.kt b/core/src/commonMain/kotlin/entity/application/ApplicationGuildCommandPermissions.kt similarity index 100% rename from core/src/main/kotlin/entity/application/ApplicationGuildCommandPermissions.kt rename to core/src/commonMain/kotlin/entity/application/ApplicationGuildCommandPermissions.kt diff --git a/core/src/main/kotlin/entity/application/ChatInputCommandCommand.kt b/core/src/commonMain/kotlin/entity/application/ChatInputCommandCommand.kt similarity index 100% rename from core/src/main/kotlin/entity/application/ChatInputCommandCommand.kt rename to core/src/commonMain/kotlin/entity/application/ChatInputCommandCommand.kt diff --git a/core/src/main/kotlin/entity/application/MessageCommand.kt b/core/src/commonMain/kotlin/entity/application/MessageCommand.kt similarity index 100% rename from core/src/main/kotlin/entity/application/MessageCommand.kt rename to core/src/commonMain/kotlin/entity/application/MessageCommand.kt diff --git a/core/src/main/kotlin/entity/application/UserCommand.kt b/core/src/commonMain/kotlin/entity/application/UserCommand.kt similarity index 100% rename from core/src/main/kotlin/entity/application/UserCommand.kt rename to core/src/commonMain/kotlin/entity/application/UserCommand.kt diff --git a/core/src/main/kotlin/entity/automoderation/AutoModerationAction.kt b/core/src/commonMain/kotlin/entity/automoderation/AutoModerationAction.kt similarity index 100% rename from core/src/main/kotlin/entity/automoderation/AutoModerationAction.kt rename to core/src/commonMain/kotlin/entity/automoderation/AutoModerationAction.kt diff --git a/core/src/main/kotlin/entity/automoderation/AutoModerationRule.kt b/core/src/commonMain/kotlin/entity/automoderation/AutoModerationRule.kt similarity index 100% rename from core/src/main/kotlin/entity/automoderation/AutoModerationRule.kt rename to core/src/commonMain/kotlin/entity/automoderation/AutoModerationRule.kt diff --git a/core/src/main/kotlin/entity/channel/CategorizableChannel.kt b/core/src/commonMain/kotlin/entity/channel/CategorizableChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/CategorizableChannel.kt rename to core/src/commonMain/kotlin/entity/channel/CategorizableChannel.kt diff --git a/core/src/main/kotlin/entity/channel/Category.kt b/core/src/commonMain/kotlin/entity/channel/Category.kt similarity index 95% rename from core/src/main/kotlin/entity/channel/Category.kt rename to core/src/commonMain/kotlin/entity/channel/Category.kt index c9d7ac4902ac..76b2cdfc13e7 100644 --- a/core/src/main/kotlin/entity/channel/Category.kt +++ b/core/src/commonMain/kotlin/entity/channel/Category.kt @@ -10,7 +10,7 @@ import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.Entity import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash /** * An instance of a Discord category associated to a [guild]. @@ -42,7 +42,7 @@ public class Category( Category(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/channel/Channel.kt b/core/src/commonMain/kotlin/entity/channel/Channel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/Channel.kt rename to core/src/commonMain/kotlin/entity/channel/Channel.kt diff --git a/core/src/main/kotlin/entity/channel/DmChannel.kt b/core/src/commonMain/kotlin/entity/channel/DmChannel.kt similarity index 97% rename from core/src/main/kotlin/entity/channel/DmChannel.kt rename to core/src/commonMain/kotlin/entity/channel/DmChannel.kt index 07e64539975c..e03ac7476e38 100644 --- a/core/src/main/kotlin/entity/channel/DmChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/DmChannel.kt @@ -8,13 +8,13 @@ import dev.kord.core.behavior.UserBehavior import dev.kord.core.behavior.channel.ChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.User +import dev.kord.core.hash import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.asFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.map -import java.util.* /** * An instance of a Discord DM channel. @@ -60,7 +60,7 @@ public data class DmChannel( DmChannel(data, kord, strategy.supply(kord)) - override fun hashCode(): Int = Objects.hash(id) + override fun hashCode(): Int = hash(id) override fun equals(other: Any?): Boolean = when (other) { is ChannelBehavior -> other.id == id diff --git a/core/src/main/kotlin/entity/channel/ForumChannel.kt b/core/src/commonMain/kotlin/entity/channel/ForumChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/ForumChannel.kt rename to core/src/commonMain/kotlin/entity/channel/ForumChannel.kt diff --git a/core/src/main/kotlin/entity/channel/GuildChannel.kt b/core/src/commonMain/kotlin/entity/channel/GuildChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/GuildChannel.kt rename to core/src/commonMain/kotlin/entity/channel/GuildChannel.kt diff --git a/core/src/main/kotlin/entity/channel/GuildMessageChannel.kt b/core/src/commonMain/kotlin/entity/channel/GuildMessageChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/GuildMessageChannel.kt rename to core/src/commonMain/kotlin/entity/channel/GuildMessageChannel.kt diff --git a/core/src/main/kotlin/entity/channel/MessageChannel.kt b/core/src/commonMain/kotlin/entity/channel/MessageChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/MessageChannel.kt rename to core/src/commonMain/kotlin/entity/channel/MessageChannel.kt diff --git a/core/src/main/kotlin/entity/channel/NewsChannel.kt b/core/src/commonMain/kotlin/entity/channel/NewsChannel.kt similarity index 94% rename from core/src/main/kotlin/entity/channel/NewsChannel.kt rename to core/src/commonMain/kotlin/entity/channel/NewsChannel.kt index 187e6e9ffdba..348edf553091 100644 --- a/core/src/main/kotlin/entity/channel/NewsChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/NewsChannel.kt @@ -7,7 +7,7 @@ import dev.kord.core.behavior.channel.NewsChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash /** * An instance of a Discord News Channel associated to a guild. @@ -18,7 +18,7 @@ public class NewsChannel( override val supplier: EntitySupplier = kord.defaultSupplier ) : CategorizableChannel, TopGuildMessageChannel, ThreadParentChannel, NewsChannelBehavior { - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is TopGuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/channel/ResolvedChannel.kt b/core/src/commonMain/kotlin/entity/channel/ResolvedChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/ResolvedChannel.kt rename to core/src/commonMain/kotlin/entity/channel/ResolvedChannel.kt diff --git a/core/src/main/kotlin/entity/channel/StageVoiceChannel.kt b/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt similarity index 95% rename from core/src/main/kotlin/entity/channel/StageVoiceChannel.kt rename to core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt index 02468b01ed26..31ce9c43de74 100644 --- a/core/src/main/kotlin/entity/channel/StageVoiceChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/StageVoiceChannel.kt @@ -8,7 +8,7 @@ import dev.kord.core.behavior.channel.StageChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash /** * An instance of a [Discord Stage Channel](https://support.discord.com/hc/en-us/articles/1500005513722) @@ -42,7 +42,7 @@ public class StageChannel( override suspend fun asChannelOrNull(): StageChannel = this - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/channel/TextChannel.kt b/core/src/commonMain/kotlin/entity/channel/TextChannel.kt similarity index 96% rename from core/src/main/kotlin/entity/channel/TextChannel.kt rename to core/src/commonMain/kotlin/entity/channel/TextChannel.kt index 4bb53c2b6f69..ed37d7925eed 100644 --- a/core/src/main/kotlin/entity/channel/TextChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/TextChannel.kt @@ -9,7 +9,7 @@ import dev.kord.core.behavior.channel.TextChannelBehavior import dev.kord.core.cache.data.ChannelData import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy -import java.util.* +import dev.kord.core.hash import kotlin.time.Duration /** @@ -47,7 +47,7 @@ public class TextChannel( override suspend fun asChannelOrNull(): TextChannel = this - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/channel/ThreadParentChannel.kt b/core/src/commonMain/kotlin/entity/channel/ThreadParentChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/ThreadParentChannel.kt rename to core/src/commonMain/kotlin/entity/channel/ThreadParentChannel.kt diff --git a/core/src/main/kotlin/entity/channel/TopGuildChannel.kt b/core/src/commonMain/kotlin/entity/channel/TopGuildChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/TopGuildChannel.kt rename to core/src/commonMain/kotlin/entity/channel/TopGuildChannel.kt diff --git a/core/src/main/kotlin/entity/channel/TopGuildMessageChannel.kt b/core/src/commonMain/kotlin/entity/channel/TopGuildMessageChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/TopGuildMessageChannel.kt rename to core/src/commonMain/kotlin/entity/channel/TopGuildMessageChannel.kt diff --git a/core/src/main/kotlin/entity/channel/VoiceChannel.kt b/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt similarity index 97% rename from core/src/main/kotlin/entity/channel/VoiceChannel.kt rename to core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt index e5d2de37face..46db97f0372d 100644 --- a/core/src/main/kotlin/entity/channel/VoiceChannel.kt +++ b/core/src/commonMain/kotlin/entity/channel/VoiceChannel.kt @@ -16,7 +16,7 @@ import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.firstOrNull -import java.util.* +import dev.kord.core.hash /** * An instance of a Discord Voice Channel associated to a guild. @@ -76,7 +76,7 @@ public class VoiceChannel( override suspend fun asChannelOrNull(): VoiceChannel = this - override fun hashCode(): Int = Objects.hash(id, guildId) + override fun hashCode(): Int = hash(id, guildId) override fun equals(other: Any?): Boolean = when (other) { is GuildChannelBehavior -> other.id == id && other.guildId == guildId diff --git a/core/src/main/kotlin/entity/channel/WelcomeScreenChannel.kt b/core/src/commonMain/kotlin/entity/channel/WelcomeScreenChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/WelcomeScreenChannel.kt rename to core/src/commonMain/kotlin/entity/channel/WelcomeScreenChannel.kt diff --git a/core/src/main/kotlin/entity/channel/thread/DeletedThreadChannel.kt b/core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/thread/DeletedThreadChannel.kt rename to core/src/commonMain/kotlin/entity/channel/thread/DeletedThreadChannel.kt diff --git a/core/src/main/kotlin/entity/channel/thread/NewsChannelThread.kt b/core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/thread/NewsChannelThread.kt rename to core/src/commonMain/kotlin/entity/channel/thread/NewsChannelThread.kt diff --git a/core/src/main/kotlin/entity/channel/thread/TextChannelThread.kt b/core/src/commonMain/kotlin/entity/channel/thread/TextChannelThread.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/thread/TextChannelThread.kt rename to core/src/commonMain/kotlin/entity/channel/thread/TextChannelThread.kt diff --git a/core/src/main/kotlin/entity/channel/thread/ThreadChannel.kt b/core/src/commonMain/kotlin/entity/channel/thread/ThreadChannel.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/thread/ThreadChannel.kt rename to core/src/commonMain/kotlin/entity/channel/thread/ThreadChannel.kt diff --git a/core/src/main/kotlin/entity/channel/thread/ThreadMember.kt b/core/src/commonMain/kotlin/entity/channel/thread/ThreadMember.kt similarity index 100% rename from core/src/main/kotlin/entity/channel/thread/ThreadMember.kt rename to core/src/commonMain/kotlin/entity/channel/thread/ThreadMember.kt diff --git a/core/src/main/kotlin/entity/component/ActionRowComponent.kt b/core/src/commonMain/kotlin/entity/component/ActionRowComponent.kt similarity index 100% rename from core/src/main/kotlin/entity/component/ActionRowComponent.kt rename to core/src/commonMain/kotlin/entity/component/ActionRowComponent.kt diff --git a/core/src/main/kotlin/entity/component/ButtonComponent.kt b/core/src/commonMain/kotlin/entity/component/ButtonComponent.kt similarity index 100% rename from core/src/main/kotlin/entity/component/ButtonComponent.kt rename to core/src/commonMain/kotlin/entity/component/ButtonComponent.kt diff --git a/core/src/main/kotlin/entity/component/Component.kt b/core/src/commonMain/kotlin/entity/component/Component.kt similarity index 100% rename from core/src/main/kotlin/entity/component/Component.kt rename to core/src/commonMain/kotlin/entity/component/Component.kt diff --git a/core/src/main/kotlin/entity/component/SelectMenuComponent.kt b/core/src/commonMain/kotlin/entity/component/SelectMenuComponent.kt similarity index 99% rename from core/src/main/kotlin/entity/component/SelectMenuComponent.kt rename to core/src/commonMain/kotlin/entity/component/SelectMenuComponent.kt index f63d6d260117..eaa6047b3712 100644 --- a/core/src/main/kotlin/entity/component/SelectMenuComponent.kt +++ b/core/src/commonMain/kotlin/entity/component/SelectMenuComponent.kt @@ -10,6 +10,7 @@ import dev.kord.core.cache.data.ComponentData import dev.kord.core.cache.data.SelectOptionData import dev.kord.core.entity.Message import dev.kord.core.entity.interaction.SelectMenuInteraction +import kotlin.jvm.JvmName /** * An interactive dropdown menu rendered on a [Message] that consists of multiple [options]. diff --git a/core/src/main/kotlin/entity/component/TextInputComponent.kt b/core/src/commonMain/kotlin/entity/component/TextInputComponent.kt similarity index 100% rename from core/src/main/kotlin/entity/component/TextInputComponent.kt rename to core/src/commonMain/kotlin/entity/component/TextInputComponent.kt diff --git a/core/src/main/kotlin/entity/component/UnknownComponent.kt b/core/src/commonMain/kotlin/entity/component/UnknownComponent.kt similarity index 100% rename from core/src/main/kotlin/entity/component/UnknownComponent.kt rename to core/src/commonMain/kotlin/entity/component/UnknownComponent.kt diff --git a/core/src/main/kotlin/entity/interaction/ActionInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ActionInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ActionInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ActionInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/ApplicationCommandInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ApplicationCommandInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ApplicationCommandInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ApplicationCommandInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/AutoCompleteInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/AutoCompleteInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/AutoCompleteInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/AutoCompleteInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/ButtonInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ButtonInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ButtonInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ButtonInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/ChatInputCommandInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ChatInputCommandInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ChatInputCommandInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ChatInputCommandInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/ComponentInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ComponentInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ComponentInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ComponentInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/DataInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/DataInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/DataInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/DataInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/GlobalInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/GlobalInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/GlobalInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/GlobalInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/GuildInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/GuildInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/GuildInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/GuildInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/Interaction.kt b/core/src/commonMain/kotlin/entity/interaction/Interaction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/Interaction.kt rename to core/src/commonMain/kotlin/entity/interaction/Interaction.kt diff --git a/core/src/main/kotlin/entity/interaction/InteractionCommand.kt b/core/src/commonMain/kotlin/entity/interaction/InteractionCommand.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/InteractionCommand.kt rename to core/src/commonMain/kotlin/entity/interaction/InteractionCommand.kt diff --git a/core/src/main/kotlin/entity/interaction/MessageCommandInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/MessageCommandInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/MessageCommandInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/MessageCommandInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/ModalSubmitInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/ModalSubmitInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ModalSubmitInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/ModalSubmitInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/OptionValue.kt b/core/src/commonMain/kotlin/entity/interaction/OptionValue.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/OptionValue.kt rename to core/src/commonMain/kotlin/entity/interaction/OptionValue.kt diff --git a/core/src/main/kotlin/entity/interaction/ResolvedObjects.kt b/core/src/commonMain/kotlin/entity/interaction/ResolvedObjects.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/ResolvedObjects.kt rename to core/src/commonMain/kotlin/entity/interaction/ResolvedObjects.kt diff --git a/core/src/main/kotlin/entity/interaction/SelectMenuInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/SelectMenuInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/SelectMenuInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/UserCommandInteraction.kt b/core/src/commonMain/kotlin/entity/interaction/UserCommandInteraction.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/UserCommandInteraction.kt rename to core/src/commonMain/kotlin/entity/interaction/UserCommandInteraction.kt diff --git a/core/src/main/kotlin/entity/interaction/followup/EphemeralFollowupMessage.kt b/core/src/commonMain/kotlin/entity/interaction/followup/EphemeralFollowupMessage.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/followup/EphemeralFollowupMessage.kt rename to core/src/commonMain/kotlin/entity/interaction/followup/EphemeralFollowupMessage.kt diff --git a/core/src/main/kotlin/entity/interaction/followup/FollowupMessage.kt b/core/src/commonMain/kotlin/entity/interaction/followup/FollowupMessage.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/followup/FollowupMessage.kt rename to core/src/commonMain/kotlin/entity/interaction/followup/FollowupMessage.kt diff --git a/core/src/main/kotlin/entity/interaction/followup/PublicFollowupMessage.kt b/core/src/commonMain/kotlin/entity/interaction/followup/PublicFollowupMessage.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/followup/PublicFollowupMessage.kt rename to core/src/commonMain/kotlin/entity/interaction/followup/PublicFollowupMessage.kt diff --git a/core/src/main/kotlin/entity/interaction/response/EphemeralMessageInteractionResponse.kt b/core/src/commonMain/kotlin/entity/interaction/response/EphemeralMessageInteractionResponse.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/response/EphemeralMessageInteractionResponse.kt rename to core/src/commonMain/kotlin/entity/interaction/response/EphemeralMessageInteractionResponse.kt diff --git a/core/src/main/kotlin/entity/interaction/response/MessageInteractionResponse.kt b/core/src/commonMain/kotlin/entity/interaction/response/MessageInteractionResponse.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/response/MessageInteractionResponse.kt rename to core/src/commonMain/kotlin/entity/interaction/response/MessageInteractionResponse.kt diff --git a/core/src/main/kotlin/entity/interaction/response/PublicMessageInteractionResponse.kt b/core/src/commonMain/kotlin/entity/interaction/response/PublicMessageInteractionResponse.kt similarity index 100% rename from core/src/main/kotlin/entity/interaction/response/PublicMessageInteractionResponse.kt rename to core/src/commonMain/kotlin/entity/interaction/response/PublicMessageInteractionResponse.kt diff --git a/core/src/main/kotlin/event/Event.kt b/core/src/commonMain/kotlin/event/Event.kt similarity index 100% rename from core/src/main/kotlin/event/Event.kt rename to core/src/commonMain/kotlin/event/Event.kt diff --git a/core/src/main/kotlin/event/automoderation/AutoModerationActionExecutionEvent.kt b/core/src/commonMain/kotlin/event/automoderation/AutoModerationActionExecutionEvent.kt similarity index 100% rename from core/src/main/kotlin/event/automoderation/AutoModerationActionExecutionEvent.kt rename to core/src/commonMain/kotlin/event/automoderation/AutoModerationActionExecutionEvent.kt diff --git a/core/src/main/kotlin/event/automoderation/AutoModerationEvent.kt b/core/src/commonMain/kotlin/event/automoderation/AutoModerationEvent.kt similarity index 100% rename from core/src/main/kotlin/event/automoderation/AutoModerationEvent.kt rename to core/src/commonMain/kotlin/event/automoderation/AutoModerationEvent.kt diff --git a/core/src/main/kotlin/event/automoderation/AutoModerationRuleConfigurationEvent.kt b/core/src/commonMain/kotlin/event/automoderation/AutoModerationRuleConfigurationEvent.kt similarity index 100% rename from core/src/main/kotlin/event/automoderation/AutoModerationRuleConfigurationEvent.kt rename to core/src/commonMain/kotlin/event/automoderation/AutoModerationRuleConfigurationEvent.kt diff --git a/core/src/main/kotlin/event/automoderation/data/AutoModerationActionExecutionEventData.kt b/core/src/commonMain/kotlin/event/automoderation/data/AutoModerationActionExecutionEventData.kt similarity index 100% rename from core/src/main/kotlin/event/automoderation/data/AutoModerationActionExecutionEventData.kt rename to core/src/commonMain/kotlin/event/automoderation/data/AutoModerationActionExecutionEventData.kt diff --git a/core/src/main/kotlin/event/channel/ChannelCreateEvent.kt b/core/src/commonMain/kotlin/event/channel/ChannelCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/ChannelCreateEvent.kt rename to core/src/commonMain/kotlin/event/channel/ChannelCreateEvent.kt diff --git a/core/src/main/kotlin/event/channel/ChannelDeleteEvent.kt b/core/src/commonMain/kotlin/event/channel/ChannelDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/ChannelDeleteEvent.kt rename to core/src/commonMain/kotlin/event/channel/ChannelDeleteEvent.kt diff --git a/core/src/main/kotlin/event/channel/ChannelPinsUpdateEvent.kt b/core/src/commonMain/kotlin/event/channel/ChannelPinsUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/ChannelPinsUpdateEvent.kt rename to core/src/commonMain/kotlin/event/channel/ChannelPinsUpdateEvent.kt diff --git a/core/src/main/kotlin/event/channel/ChannelUpdateEvent.kt b/core/src/commonMain/kotlin/event/channel/ChannelUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/ChannelUpdateEvent.kt rename to core/src/commonMain/kotlin/event/channel/ChannelUpdateEvent.kt diff --git a/core/src/main/kotlin/event/channel/TypingStartEvent.kt b/core/src/commonMain/kotlin/event/channel/TypingStartEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/TypingStartEvent.kt rename to core/src/commonMain/kotlin/event/channel/TypingStartEvent.kt diff --git a/core/src/main/kotlin/event/channel/data/ChannelPinsUpdateEventData.kt b/core/src/commonMain/kotlin/event/channel/data/ChannelPinsUpdateEventData.kt similarity index 100% rename from core/src/main/kotlin/event/channel/data/ChannelPinsUpdateEventData.kt rename to core/src/commonMain/kotlin/event/channel/data/ChannelPinsUpdateEventData.kt diff --git a/core/src/main/kotlin/event/channel/data/TypingStartEventData.kt b/core/src/commonMain/kotlin/event/channel/data/TypingStartEventData.kt similarity index 100% rename from core/src/main/kotlin/event/channel/data/TypingStartEventData.kt rename to core/src/commonMain/kotlin/event/channel/data/TypingStartEventData.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadCreateEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadCreateEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadCreateEvent.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadDeleteEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadDeleteEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadDeleteEvent.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadListSyncEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadListSyncEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadListSyncEvent.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadMemberUpdateEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadMemberUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadMemberUpdateEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadMemberUpdateEvent.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadMembersUpdateEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadMembersUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadMembersUpdateEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadMembersUpdateEvent.kt diff --git a/core/src/main/kotlin/event/channel/thread/ThreadUpdateEvent.kt b/core/src/commonMain/kotlin/event/channel/thread/ThreadUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/channel/thread/ThreadUpdateEvent.kt rename to core/src/commonMain/kotlin/event/channel/thread/ThreadUpdateEvent.kt diff --git a/core/src/main/kotlin/event/gateway/Events.kt b/core/src/commonMain/kotlin/event/gateway/Events.kt similarity index 100% rename from core/src/main/kotlin/event/gateway/Events.kt rename to core/src/commonMain/kotlin/event/gateway/Events.kt diff --git a/core/src/main/kotlin/event/guild/BanAddEvent.kt b/core/src/commonMain/kotlin/event/guild/BanAddEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/BanAddEvent.kt rename to core/src/commonMain/kotlin/event/guild/BanAddEvent.kt diff --git a/core/src/main/kotlin/event/guild/BanRemoveEvent.kt b/core/src/commonMain/kotlin/event/guild/BanRemoveEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/BanRemoveEvent.kt rename to core/src/commonMain/kotlin/event/guild/BanRemoveEvent.kt diff --git a/core/src/main/kotlin/event/guild/EmojisUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/EmojisUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/EmojisUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/EmojisUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildAuditLogEntryCreateEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildAuditLogEntryCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildAuditLogEntryCreateEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildAuditLogEntryCreateEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildCreateEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildCreateEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildCreateEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildDeleteEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildDeleteEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildDeleteEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildScheduledEventCreateEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildScheduledEventCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildScheduledEventCreateEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildScheduledEventCreateEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildScheduledEventDeleteEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildScheduledEventDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildScheduledEventDeleteEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildScheduledEventDeleteEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildScheduledEventEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildScheduledEventEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildScheduledEventEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildScheduledEventEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildScheduledEventUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildScheduledEventUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildScheduledEventUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildScheduledEventUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildScheduledEventUserEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildScheduledEventUserEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildScheduledEventUserEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildScheduledEventUserEvent.kt diff --git a/core/src/main/kotlin/event/guild/GuildUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/GuildUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/GuildUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/GuildUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/IntegrationCreateEvent.kt b/core/src/commonMain/kotlin/event/guild/IntegrationCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/IntegrationCreateEvent.kt rename to core/src/commonMain/kotlin/event/guild/IntegrationCreateEvent.kt diff --git a/core/src/main/kotlin/event/guild/IntegrationDeleteEvent.kt b/core/src/commonMain/kotlin/event/guild/IntegrationDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/IntegrationDeleteEvent.kt rename to core/src/commonMain/kotlin/event/guild/IntegrationDeleteEvent.kt diff --git a/core/src/main/kotlin/event/guild/IntegrationUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/IntegrationUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/IntegrationUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/IntegrationUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/IntegrationsUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/IntegrationsUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/IntegrationsUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/IntegrationsUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/InviteCreateEvent.kt b/core/src/commonMain/kotlin/event/guild/InviteCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/InviteCreateEvent.kt rename to core/src/commonMain/kotlin/event/guild/InviteCreateEvent.kt diff --git a/core/src/main/kotlin/event/guild/InviteDeleteEvent.kt b/core/src/commonMain/kotlin/event/guild/InviteDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/InviteDeleteEvent.kt rename to core/src/commonMain/kotlin/event/guild/InviteDeleteEvent.kt diff --git a/core/src/main/kotlin/event/guild/MemberJoinEvent.kt b/core/src/commonMain/kotlin/event/guild/MemberJoinEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/MemberJoinEvent.kt rename to core/src/commonMain/kotlin/event/guild/MemberJoinEvent.kt diff --git a/core/src/main/kotlin/event/guild/MemberLeaveEvent.kt b/core/src/commonMain/kotlin/event/guild/MemberLeaveEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/MemberLeaveEvent.kt rename to core/src/commonMain/kotlin/event/guild/MemberLeaveEvent.kt diff --git a/core/src/main/kotlin/event/guild/MemberUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/MemberUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/MemberUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/MemberUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/MembersChunkEvent.kt b/core/src/commonMain/kotlin/event/guild/MembersChunkEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/MembersChunkEvent.kt rename to core/src/commonMain/kotlin/event/guild/MembersChunkEvent.kt diff --git a/core/src/main/kotlin/event/guild/VoiceServerUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/VoiceServerUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/VoiceServerUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/VoiceServerUpdateEvent.kt diff --git a/core/src/main/kotlin/event/guild/WebhookUpdateEvent.kt b/core/src/commonMain/kotlin/event/guild/WebhookUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/guild/WebhookUpdateEvent.kt rename to core/src/commonMain/kotlin/event/guild/WebhookUpdateEvent.kt diff --git a/core/src/main/kotlin/event/interaction/ApplicationCommandCreate.kt b/core/src/commonMain/kotlin/event/interaction/ApplicationCommandCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ApplicationCommandCreate.kt rename to core/src/commonMain/kotlin/event/interaction/ApplicationCommandCreate.kt diff --git a/core/src/main/kotlin/event/interaction/ApplicationCommandDelete.kt b/core/src/commonMain/kotlin/event/interaction/ApplicationCommandDelete.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ApplicationCommandDelete.kt rename to core/src/commonMain/kotlin/event/interaction/ApplicationCommandDelete.kt diff --git a/core/src/main/kotlin/event/interaction/ApplicationCommandInteractionCreate.kt b/core/src/commonMain/kotlin/event/interaction/ApplicationCommandInteractionCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ApplicationCommandInteractionCreate.kt rename to core/src/commonMain/kotlin/event/interaction/ApplicationCommandInteractionCreate.kt diff --git a/core/src/main/kotlin/event/interaction/ApplicationCommandPermissionsUpdateEvent.kt b/core/src/commonMain/kotlin/event/interaction/ApplicationCommandPermissionsUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ApplicationCommandPermissionsUpdateEvent.kt rename to core/src/commonMain/kotlin/event/interaction/ApplicationCommandPermissionsUpdateEvent.kt diff --git a/core/src/main/kotlin/event/interaction/ApplicationCommandUpdate.kt b/core/src/commonMain/kotlin/event/interaction/ApplicationCommandUpdate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ApplicationCommandUpdate.kt rename to core/src/commonMain/kotlin/event/interaction/ApplicationCommandUpdate.kt diff --git a/core/src/main/kotlin/event/interaction/AutoCompleteInteractionCreate.kt b/core/src/commonMain/kotlin/event/interaction/AutoCompleteInteractionCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/AutoCompleteInteractionCreate.kt rename to core/src/commonMain/kotlin/event/interaction/AutoCompleteInteractionCreate.kt diff --git a/core/src/main/kotlin/event/interaction/ComponentInteractionCreate.kt b/core/src/commonMain/kotlin/event/interaction/ComponentInteractionCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ComponentInteractionCreate.kt rename to core/src/commonMain/kotlin/event/interaction/ComponentInteractionCreate.kt diff --git a/core/src/main/kotlin/event/interaction/InteractionCreate.kt b/core/src/commonMain/kotlin/event/interaction/InteractionCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/InteractionCreate.kt rename to core/src/commonMain/kotlin/event/interaction/InteractionCreate.kt diff --git a/core/src/main/kotlin/event/interaction/ModalSubmitInteractionCreate.kt b/core/src/commonMain/kotlin/event/interaction/ModalSubmitInteractionCreate.kt similarity index 100% rename from core/src/main/kotlin/event/interaction/ModalSubmitInteractionCreate.kt rename to core/src/commonMain/kotlin/event/interaction/ModalSubmitInteractionCreate.kt diff --git a/core/src/main/kotlin/event/message/MessageBulkDeleteEvent.kt b/core/src/commonMain/kotlin/event/message/MessageBulkDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/MessageBulkDeleteEvent.kt rename to core/src/commonMain/kotlin/event/message/MessageBulkDeleteEvent.kt diff --git a/core/src/main/kotlin/event/message/MessageCreateEvent.kt b/core/src/commonMain/kotlin/event/message/MessageCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/MessageCreateEvent.kt rename to core/src/commonMain/kotlin/event/message/MessageCreateEvent.kt diff --git a/core/src/main/kotlin/event/message/MessageDeleteEvent.kt b/core/src/commonMain/kotlin/event/message/MessageDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/MessageDeleteEvent.kt rename to core/src/commonMain/kotlin/event/message/MessageDeleteEvent.kt diff --git a/core/src/main/kotlin/event/message/MessageUpdateEvent.kt b/core/src/commonMain/kotlin/event/message/MessageUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/MessageUpdateEvent.kt rename to core/src/commonMain/kotlin/event/message/MessageUpdateEvent.kt diff --git a/core/src/main/kotlin/event/message/ReactionAddEvent.kt b/core/src/commonMain/kotlin/event/message/ReactionAddEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/ReactionAddEvent.kt rename to core/src/commonMain/kotlin/event/message/ReactionAddEvent.kt diff --git a/core/src/main/kotlin/event/message/ReactionRemoveAllEvent.kt b/core/src/commonMain/kotlin/event/message/ReactionRemoveAllEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/ReactionRemoveAllEvent.kt rename to core/src/commonMain/kotlin/event/message/ReactionRemoveAllEvent.kt diff --git a/core/src/main/kotlin/event/message/ReactionRemoveEmojiEvent.kt b/core/src/commonMain/kotlin/event/message/ReactionRemoveEmojiEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/ReactionRemoveEmojiEvent.kt rename to core/src/commonMain/kotlin/event/message/ReactionRemoveEmojiEvent.kt diff --git a/core/src/main/kotlin/event/message/ReactionRemoveEvent.kt b/core/src/commonMain/kotlin/event/message/ReactionRemoveEvent.kt similarity index 100% rename from core/src/main/kotlin/event/message/ReactionRemoveEvent.kt rename to core/src/commonMain/kotlin/event/message/ReactionRemoveEvent.kt diff --git a/core/src/main/kotlin/event/role/RoleCreateEvent.kt b/core/src/commonMain/kotlin/event/role/RoleCreateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/role/RoleCreateEvent.kt rename to core/src/commonMain/kotlin/event/role/RoleCreateEvent.kt diff --git a/core/src/main/kotlin/event/role/RoleDeleteEvent.kt b/core/src/commonMain/kotlin/event/role/RoleDeleteEvent.kt similarity index 100% rename from core/src/main/kotlin/event/role/RoleDeleteEvent.kt rename to core/src/commonMain/kotlin/event/role/RoleDeleteEvent.kt diff --git a/core/src/main/kotlin/event/role/RoleUpdateEvent.kt b/core/src/commonMain/kotlin/event/role/RoleUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/role/RoleUpdateEvent.kt rename to core/src/commonMain/kotlin/event/role/RoleUpdateEvent.kt diff --git a/core/src/main/kotlin/event/user/PresenceUpdateEvent.kt b/core/src/commonMain/kotlin/event/user/PresenceUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/user/PresenceUpdateEvent.kt rename to core/src/commonMain/kotlin/event/user/PresenceUpdateEvent.kt diff --git a/core/src/main/kotlin/event/user/UserUpdateEvent.kt b/core/src/commonMain/kotlin/event/user/UserUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/user/UserUpdateEvent.kt rename to core/src/commonMain/kotlin/event/user/UserUpdateEvent.kt diff --git a/core/src/main/kotlin/event/user/VoiceStateUpdateEvent.kt b/core/src/commonMain/kotlin/event/user/VoiceStateUpdateEvent.kt similarity index 100% rename from core/src/main/kotlin/event/user/VoiceStateUpdateEvent.kt rename to core/src/commonMain/kotlin/event/user/VoiceStateUpdateEvent.kt diff --git a/core/src/main/kotlin/exception/EntityNotFoundException.kt b/core/src/commonMain/kotlin/exception/EntityNotFoundException.kt similarity index 100% rename from core/src/main/kotlin/exception/EntityNotFoundException.kt rename to core/src/commonMain/kotlin/exception/EntityNotFoundException.kt diff --git a/core/src/main/kotlin/exception/GatewayNotFoundException.kt b/core/src/commonMain/kotlin/exception/GatewayNotFoundException.kt similarity index 100% rename from core/src/main/kotlin/exception/GatewayNotFoundException.kt rename to core/src/commonMain/kotlin/exception/GatewayNotFoundException.kt diff --git a/core/src/main/kotlin/exception/KordInitializationException.kt b/core/src/commonMain/kotlin/exception/KordInitializationException.kt similarity index 100% rename from core/src/main/kotlin/exception/KordInitializationException.kt rename to core/src/commonMain/kotlin/exception/KordInitializationException.kt diff --git a/core/src/main/kotlin/gateway/DefaultMasterGateway.kt b/core/src/commonMain/kotlin/gateway/DefaultMasterGateway.kt similarity index 100% rename from core/src/main/kotlin/gateway/DefaultMasterGateway.kt rename to core/src/commonMain/kotlin/gateway/DefaultMasterGateway.kt diff --git a/core/src/main/kotlin/gateway/MasterGateway.kt b/core/src/commonMain/kotlin/gateway/MasterGateway.kt similarity index 100% rename from core/src/main/kotlin/gateway/MasterGateway.kt rename to core/src/commonMain/kotlin/gateway/MasterGateway.kt diff --git a/core/src/main/kotlin/gateway/handler/AutoModerationEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/AutoModerationEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/AutoModerationEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/AutoModerationEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/BaseGatewayEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/BaseGatewayEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/BaseGatewayEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/BaseGatewayEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/ChannelEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/ChannelEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/ChannelEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt b/core/src/commonMain/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt similarity index 97% rename from core/src/main/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt rename to core/src/commonMain/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt index 6d80c82cb3af..8725cfa03012 100644 --- a/core/src/main/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt +++ b/core/src/commonMain/kotlin/gateway/handler/DefaultGatewayEventInterceptor.kt @@ -3,7 +3,6 @@ package dev.kord.core.gateway.handler import dev.kord.common.annotation.KordPreview import dev.kord.core.Kord import dev.kord.core.gateway.ShardEvent -import io.ktor.util.logging.* import mu.KotlinLogging import dev.kord.core.event.Event as CoreEvent @@ -60,7 +59,7 @@ public class DefaultGatewayEventInterceptor @KordPreview public constructor( } return null }.onFailure { - logger.error(it) + logger.error(it) { "" } }.getOrNull() } } diff --git a/core/src/main/kotlin/gateway/handler/GatewayEventInterceptor.kt b/core/src/commonMain/kotlin/gateway/handler/GatewayEventInterceptor.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/GatewayEventInterceptor.kt rename to core/src/commonMain/kotlin/gateway/handler/GatewayEventInterceptor.kt diff --git a/core/src/main/kotlin/gateway/handler/GuildEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/GuildEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/GuildEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/InteractionEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/InteractionEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/InteractionEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/LifeCycleEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/LifeCycleEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/LifeCycleEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/LifeCycleEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/MessageEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/MessageEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/MessageEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/ThreadEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/ThreadEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/ThreadEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/UnknownEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/UnknownEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/UnknownEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/UnknownEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/UserEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/UserEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/UserEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/VoiceEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/VoiceEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/VoiceEventHandler.kt diff --git a/core/src/main/kotlin/gateway/handler/WebhookEventHandler.kt b/core/src/commonMain/kotlin/gateway/handler/WebhookEventHandler.kt similarity index 100% rename from core/src/main/kotlin/gateway/handler/WebhookEventHandler.kt rename to core/src/commonMain/kotlin/gateway/handler/WebhookEventHandler.kt diff --git a/core/src/main/kotlin/live/LiveGuild.kt b/core/src/commonMain/kotlin/live/LiveGuild.kt similarity index 100% rename from core/src/main/kotlin/live/LiveGuild.kt rename to core/src/commonMain/kotlin/live/LiveGuild.kt diff --git a/core/src/main/kotlin/live/LiveKordEntity.kt b/core/src/commonMain/kotlin/live/LiveKordEntity.kt similarity index 100% rename from core/src/main/kotlin/live/LiveKordEntity.kt rename to core/src/commonMain/kotlin/live/LiveKordEntity.kt diff --git a/core/src/main/kotlin/live/LiveMember.kt b/core/src/commonMain/kotlin/live/LiveMember.kt similarity index 100% rename from core/src/main/kotlin/live/LiveMember.kt rename to core/src/commonMain/kotlin/live/LiveMember.kt diff --git a/core/src/main/kotlin/live/LiveMessage.kt b/core/src/commonMain/kotlin/live/LiveMessage.kt similarity index 100% rename from core/src/main/kotlin/live/LiveMessage.kt rename to core/src/commonMain/kotlin/live/LiveMessage.kt diff --git a/core/src/main/kotlin/live/LiveRole.kt b/core/src/commonMain/kotlin/live/LiveRole.kt similarity index 100% rename from core/src/main/kotlin/live/LiveRole.kt rename to core/src/commonMain/kotlin/live/LiveRole.kt diff --git a/core/src/main/kotlin/live/LiveUser.kt b/core/src/commonMain/kotlin/live/LiveUser.kt similarity index 100% rename from core/src/main/kotlin/live/LiveUser.kt rename to core/src/commonMain/kotlin/live/LiveUser.kt diff --git a/core/src/main/kotlin/live/channel/LiveCategory.kt b/core/src/commonMain/kotlin/live/channel/LiveCategory.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveCategory.kt rename to core/src/commonMain/kotlin/live/channel/LiveCategory.kt diff --git a/core/src/main/kotlin/live/channel/LiveChannel.kt b/core/src/commonMain/kotlin/live/channel/LiveChannel.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveChannel.kt rename to core/src/commonMain/kotlin/live/channel/LiveChannel.kt diff --git a/core/src/main/kotlin/live/channel/LiveDmChannel.kt b/core/src/commonMain/kotlin/live/channel/LiveDmChannel.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveDmChannel.kt rename to core/src/commonMain/kotlin/live/channel/LiveDmChannel.kt diff --git a/core/src/main/kotlin/live/channel/LiveGuildChannel.kt b/core/src/commonMain/kotlin/live/channel/LiveGuildChannel.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveGuildChannel.kt rename to core/src/commonMain/kotlin/live/channel/LiveGuildChannel.kt diff --git a/core/src/main/kotlin/live/channel/LiveGuildMessageChannel.kt b/core/src/commonMain/kotlin/live/channel/LiveGuildMessageChannel.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveGuildMessageChannel.kt rename to core/src/commonMain/kotlin/live/channel/LiveGuildMessageChannel.kt diff --git a/core/src/main/kotlin/live/channel/LiveVoiceChannel.kt b/core/src/commonMain/kotlin/live/channel/LiveVoiceChannel.kt similarity index 100% rename from core/src/main/kotlin/live/channel/LiveVoiceChannel.kt rename to core/src/commonMain/kotlin/live/channel/LiveVoiceChannel.kt diff --git a/core/src/main/kotlin/live/exception/LiveCancellationException.kt b/core/src/commonMain/kotlin/live/exception/LiveCancellationException.kt similarity index 79% rename from core/src/main/kotlin/live/exception/LiveCancellationException.kt rename to core/src/commonMain/kotlin/live/exception/LiveCancellationException.kt index 03ba7e5fed91..986a58ed7780 100644 --- a/core/src/main/kotlin/live/exception/LiveCancellationException.kt +++ b/core/src/commonMain/kotlin/live/exception/LiveCancellationException.kt @@ -1,7 +1,7 @@ package dev.kord.core.live.exception import dev.kord.core.event.Event -import java.util.concurrent.CancellationException +import kotlinx.coroutines.CancellationException public class LiveCancellationException(public val event: Event, message: String? = null) : CancellationException(message) diff --git a/core/src/main/kotlin/supplier/CacheEntitySupplier.kt b/core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt similarity index 100% rename from core/src/main/kotlin/supplier/CacheEntitySupplier.kt rename to core/src/commonMain/kotlin/supplier/CacheEntitySupplier.kt diff --git a/core/src/main/kotlin/supplier/EntitySupplier.kt b/core/src/commonMain/kotlin/supplier/EntitySupplier.kt similarity index 100% rename from core/src/main/kotlin/supplier/EntitySupplier.kt rename to core/src/commonMain/kotlin/supplier/EntitySupplier.kt diff --git a/core/src/main/kotlin/supplier/EntitySupplyStrategy.kt b/core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt similarity index 100% rename from core/src/main/kotlin/supplier/EntitySupplyStrategy.kt rename to core/src/commonMain/kotlin/supplier/EntitySupplyStrategy.kt diff --git a/core/src/main/kotlin/supplier/FallbackEntitySupplier.kt b/core/src/commonMain/kotlin/supplier/FallbackEntitySupplier.kt similarity index 100% rename from core/src/main/kotlin/supplier/FallbackEntitySupplier.kt rename to core/src/commonMain/kotlin/supplier/FallbackEntitySupplier.kt diff --git a/core/src/main/kotlin/supplier/RestEntitySupplier.kt b/core/src/commonMain/kotlin/supplier/RestEntitySupplier.kt similarity index 100% rename from core/src/main/kotlin/supplier/RestEntitySupplier.kt rename to core/src/commonMain/kotlin/supplier/RestEntitySupplier.kt diff --git a/core/src/main/kotlin/supplier/StoreEntitySupplier.kt b/core/src/commonMain/kotlin/supplier/StoreEntitySupplier.kt similarity index 100% rename from core/src/main/kotlin/supplier/StoreEntitySupplier.kt rename to core/src/commonMain/kotlin/supplier/StoreEntitySupplier.kt diff --git a/core/src/commonTest/kotlin/RandomIds.kt b/core/src/commonTest/kotlin/RandomIds.kt new file mode 100644 index 000000000000..9c49fe8c956a --- /dev/null +++ b/core/src/commonTest/kotlin/RandomIds.kt @@ -0,0 +1,11 @@ +package dev.kord.core + +import dev.kord.common.entity.Snowflake +import kotlin.random.Random +import kotlin.random.nextULong + +val ids = generateSequence { + Random.nextULong(Snowflake.validValues) // limit to valid range to guarantee distinct generated Snowflakes +}.distinct().iterator() + +fun randomId() = Snowflake(ids.next()) diff --git a/core/src/test/kotlin/UtilKtTest.kt b/core/src/commonTest/kotlin/UtilKtTest.kt similarity index 87% rename from core/src/test/kotlin/UtilKtTest.kt rename to core/src/commonTest/kotlin/UtilKtTest.kt index d6880199f814..e276e55e2005 100644 --- a/core/src/test/kotlin/UtilKtTest.kt +++ b/core/src/commonTest/kotlin/UtilKtTest.kt @@ -3,12 +3,14 @@ package dev.kord.core import dev.kord.common.entity.Snowflake import kotlinx.coroutines.flow.count import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals internal class UtilKtTest { @Test + @JsName("test1") fun `paginate forwards selects the right id`() = runTest { val flow = paginateForwards(start = Snowflake(0u), batchSize = 100, idSelector = { it }) { @@ -23,10 +25,11 @@ internal class UtilKtTest { } } - Assertions.assertEquals(1000, flow.count()) + assertEquals(1000, flow.count()) } @Test + @JsName("test2") fun `paginate backwards selects the right id`() = runTest { val flow = paginateBackwards(start = Snowflake(1000u), batchSize = 100, idSelector = { it }) { @@ -41,7 +44,7 @@ internal class UtilKtTest { } } - Assertions.assertEquals(1000, flow.count()) + assertEquals(1000, flow.count()) } } diff --git a/core/src/test/kotlin/cache/data/ComponentDataTest.kt b/core/src/commonTest/kotlin/cache/data/ComponentDataTest.kt similarity index 83% rename from core/src/test/kotlin/cache/data/ComponentDataTest.kt rename to core/src/commonTest/kotlin/cache/data/ComponentDataTest.kt index 0441ec8f81dc..ec9b840f8843 100644 --- a/core/src/test/kotlin/cache/data/ComponentDataTest.kt +++ b/core/src/commonTest/kotlin/cache/data/ComponentDataTest.kt @@ -1,16 +1,16 @@ -package cache.data +package dev.kord.core.cache.data import dev.kord.common.entity.ComponentType -import dev.kord.core.cache.data.ChatComponentData -import dev.kord.core.cache.data.ComponentData import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals class ComponentDataTest { @Test + @JsName("test1") fun `polymorphic ComponentData can be serialized`() { val type = ComponentType.ActionRow val data: ComponentData = ChatComponentData(type) diff --git a/core/src/test/kotlin/gateway/MasterGatewayTest.kt b/core/src/commonTest/kotlin/gateway/MasterGatewayTest.kt similarity index 92% rename from core/src/test/kotlin/gateway/MasterGatewayTest.kt rename to core/src/commonTest/kotlin/gateway/MasterGatewayTest.kt index 7a01a7a6c503..ed4e3f5405bc 100644 --- a/core/src/test/kotlin/gateway/MasterGatewayTest.kt +++ b/core/src/commonTest/kotlin/gateway/MasterGatewayTest.kt @@ -1,6 +1,5 @@ -package gateway +package dev.kord.core.gateway -import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.gateway.Command import dev.kord.gateway.Event import dev.kord.gateway.Gateway @@ -8,16 +7,18 @@ import dev.kord.gateway.GatewayConfiguration import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharedFlow -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.time.Duration import kotlin.time.Duration.Companion.milliseconds internal class DefaultMasterGatewayTest { @Test + @JsName("test1") fun `Gateway takes ping of single child`() { val dummy = DummyGateway() val ping = 150.milliseconds @@ -32,6 +33,7 @@ internal class DefaultMasterGatewayTest { } @Test + @JsName("test2") fun `Gateway takes ping average of multiple children`() { val dummy1 = DummyGateway() val dummy2 = DummyGateway() @@ -49,6 +51,7 @@ internal class DefaultMasterGatewayTest { } @Test + @JsName("test3") fun `Gateway returns null ping when no gateway pings`(){ val dummy = DummyGateway() diff --git a/core/src/test/kotlin/live/AbstractLiveEntityTest.kt b/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt similarity index 74% rename from core/src/test/kotlin/live/AbstractLiveEntityTest.kt rename to core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt index aaf66060e47c..2df59fe02e12 100644 --- a/core/src/test/kotlin/live/AbstractLiveEntityTest.kt +++ b/core/src/commonTest/kotlin/live/AbstractLiveEntityTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.cache.api.DataCache import dev.kord.common.entity.Snowflake @@ -6,7 +6,7 @@ import dev.kord.core.ClientResources import dev.kord.core.Kord import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor -import dev.kord.core.live.AbstractLiveKordEntity +import dev.kord.core.randomId import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.gateway.Command import dev.kord.gateway.Event @@ -15,24 +15,19 @@ import dev.kord.gateway.GatewayConfiguration import dev.kord.gateway.builder.Shards import dev.kord.rest.request.KtorRequestHandler import dev.kord.rest.service.RestClient -import equality.randomId import io.ktor.client.* +import kotlinx.atomicfu.atomic import kotlinx.coroutines.* +import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import org.junit.jupiter.api.AfterAll -import org.junit.jupiter.api.BeforeAll -import java.util.concurrent.CountDownLatch -import java.util.concurrent.TimeUnit -import java.util.concurrent.atomic.AtomicInteger +import kotlinx.coroutines.test.runTest import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext -import kotlin.test.AfterTest -import kotlin.test.assertEquals -import kotlin.test.assertFalse -import kotlin.test.assertTrue +import kotlin.test.* import kotlin.time.Duration +import kotlin.time.Duration.Companion.milliseconds abstract class AbstractLiveEntityTest { @@ -56,20 +51,19 @@ abstract class AbstractLiveEntityTest { override suspend fun stop() {} } - class CounterAtomicLatch(count: Int) { + class CounterAtomicLatch() { + private val channel = Channel() - private val countdown = CountDownLatch(count) - val latchCount get() = countdown.count + private val received = atomic(0) + val atomicCount by received - private val counter = AtomicInteger(0) - val atomicCount get() = counter.get() - - fun count() { - counter.incrementAndGet() - countdown.countDown() + suspend fun count() { + channel.send(Unit) } - fun await(timeout: Long, unit: TimeUnit) = countdown.await(timeout, unit) + suspend fun await(duration: Duration) = withTimeout(duration) { + for(unit in channel) { received.incrementAndGet() } + } } private lateinit var gateway: GatewayMock @@ -80,27 +74,23 @@ abstract class AbstractLiveEntityTest { lateinit var live: LIVE - @BeforeAll - open fun onBeforeAll() = runBlocking { + @BeforeTest + open fun onBeforeAll() = runTest { kord = createKord() guildId = randomId() } - @AfterAll - open fun onAfterAll() = runBlocking { + @AfterTest + open fun onAfterAll() = runTest { + if (::live.isInitialized && live.isActive) { + live.shutDown() + } if (kord.isActive) { kord.logout() kord.shutdown() } } - @AfterTest - open fun onAfter() { - if (this::live.isInitialized && live.isActive) { - live.shutDown() - } - } - protected open fun createKord(): Kord { gateway = GatewayMock() return Kord( @@ -117,15 +107,14 @@ abstract class AbstractLiveEntityTest { protected inline fun countdownContext( expectedCount: Int, - waitMs: Long = 5000, + wait: Duration = 5000.milliseconds, crossinline action: suspend CounterAtomicLatch.() -> Unit - ) = runBlocking { - val counter = CounterAtomicLatch(expectedCount) + ) = runTest { + val counter = CounterAtomicLatch() action(counter) - counter.await(waitMs, TimeUnit.MILLISECONDS) - assertEquals(0, counter.latchCount) + counter.await(wait) assertEquals(expectedCount, counter.atomicCount) } diff --git a/core/src/test/kotlin/live/LiveGuildTest.kt b/core/src/commonTest/kotlin/live/LiveGuildTest.kt similarity index 96% rename from core/src/test/kotlin/live/LiveGuildTest.kt rename to core/src/commonTest/kotlin/live/LiveGuildTest.kt index d798db21a7f8..1c53cacd1a97 100644 --- a/core/src/test/kotlin/live/LiveGuildTest.kt +++ b/core/src/commonTest/kotlin/live/LiveGuildTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional @@ -7,30 +7,25 @@ import dev.kord.core.cache.data.GuildData import dev.kord.core.entity.Guild import dev.kord.core.entity.ReactionEmoji import dev.kord.core.event.guild.GuildDeleteEvent -import dev.kord.core.live.* import dev.kord.core.live.exception.LiveCancellationException +import dev.kord.core.randomId import dev.kord.gateway.* -import equality.randomId import kotlinx.coroutines.job -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.JsonObject -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals import kotlin.time.Duration.Companion.seconds -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveGuildTest : AbstractLiveEntityTest() { @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveGuild( Guild( kord = kord, @@ -58,6 +53,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test1") fun `Check onEmojisUpdate is called when event is received`() { countdownContext(1) { live.onEmojisUpdate { @@ -78,6 +74,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test2") fun `Check onIntegrationsUpdate is called when event is received`() { countdownContext(1) { live.onIntegrationsUpdate { @@ -97,6 +94,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test3") fun `Check onBanAdd is called when event is received`() { countdownContext(1) { live.onBanAdd { @@ -122,6 +120,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test4") fun `Check onBanRemove is called when event is received`() { countdownContext(1) { live.onBanRemove { @@ -147,6 +146,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test5") fun `Check onPresenceUpdate is called when event is received`() { countdownContext(1) { live.onPresenceUpdate { @@ -173,6 +173,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test6") fun `Check onVoiceServerUpdate is called when event is received`() { countdownContext(1) { live.onVoiceServerUpdate { @@ -194,6 +195,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test7") fun `Check onVoiceStateUpdate is called when event is received`() { countdownContext(1) { live.onVoiceStateUpdate { @@ -223,6 +225,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test8") fun `Check onWebhookUpdate is called when event is received`() { countdownContext(1) { live.onWebhookUpdate { @@ -243,6 +246,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test9") fun `Check onRoleCreate is called when event is received`() { countdownContext(1) { live.onRoleCreate { @@ -274,6 +278,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test10") fun `Check onRoleUpdate is called when event is received`() { countdownContext(1) { live.onRoleUpdate { @@ -305,6 +310,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test11") fun `Check onRoleDelete is called when event is received`() { countdownContext(1) { live.onRoleDelete { @@ -325,6 +331,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test12") fun `Check onMemberJoin is called when event is received`() { countdownContext(1) { live.onMemberJoin { @@ -356,6 +363,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test13") fun `Check onMemberUpdate is called when event is received`() { countdownContext(1) { live.onMemberUpdate { @@ -383,6 +391,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test14") fun `Check onMemberLeave is called when event is received`() { countdownContext(1) { live.onMemberLeave { @@ -408,6 +417,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test15") fun `Check onReactionAdd is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -433,6 +443,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test16") fun `Check onReactionAdd with specific reaction is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -462,6 +473,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test17") fun `Check onReactionRemove is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -488,6 +500,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test18") fun `Check onReactionRemove with specific reaction is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -517,6 +530,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test19") fun `Check onReactionRemoveAll is called when event is received`() { countdownContext(1) { live.onReactionRemoveAll { @@ -538,6 +552,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test20") fun `Check onMessageCreate is called when event is received`() { countdownContext(1) { live.onMessageCreate { @@ -576,6 +591,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test21") fun `Check onMessageUpdate is called when event is received`() { countdownContext(1) { live.onMessageUpdate { @@ -597,6 +613,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test22") fun `Check onMessageDelete is called when event is received`() { countdownContext(1) { live.onMessageDelete { @@ -618,6 +635,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test23") fun `Check onChannelCreate is called when event is received`() { countdownContext(1) { live.onChannelCreate { @@ -639,6 +657,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test24") fun `Check onChannelUpdate is called when event is received`() { countdownContext(1) { live.onChannelUpdate { @@ -660,6 +679,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test25") fun `Check onChannelDelete is called when event is received`() { countdownContext(1) { live.onChannelDelete { @@ -681,6 +701,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test26") fun `Check onGuildCreate is called when event is received`() { countdownContext(1) { live.onGuildCreate { @@ -725,6 +746,7 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test + @JsName("test27") fun `Check onGuildUpdate is called when event is received`() { countdownContext(1) { live.onGuildUpdate { @@ -769,13 +791,16 @@ class LiveGuildTest : AbstractLiveEntityTest() { } @Test - fun `Check if live entity is completed when event the guild delete event is received`() { + @JsName("test28") + fun `Check if live entity is completed when event the guild delete event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as GuildDeleteEvent assertEquals(guildId, event.guildId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(guildId) { diff --git a/core/src/test/kotlin/live/LiveKordEntityTest.kt b/core/src/commonTest/kotlin/live/LiveKordEntityTest.kt similarity index 84% rename from core/src/test/kotlin/live/LiveKordEntityTest.kt rename to core/src/commonTest/kotlin/live/LiveKordEntityTest.kt index f7bc726ad425..69d84a05a029 100644 --- a/core/src/test/kotlin/live/LiveKordEntityTest.kt +++ b/core/src/commonTest/kotlin/live/LiveKordEntityTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.* import dev.kord.core.Kord @@ -7,30 +7,26 @@ import dev.kord.core.event.Event import dev.kord.core.event.guild.BanAddEvent import dev.kord.core.event.guild.GuildDeleteEvent import dev.kord.core.event.message.ReactionAddEvent -import dev.kord.core.live.AbstractLiveKordEntity import dev.kord.core.live.exception.LiveCancellationException -import dev.kord.core.live.on +import dev.kord.core.randomId import dev.kord.gateway.GuildBanAdd import dev.kord.gateway.GuildDelete import dev.kord.gateway.MessageReactionAdd -import equality.randomId -import kotlinx.coroutines.* -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.job +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.* +import kotlin.time.Duration.Companion.milliseconds -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveKordEntityTest : AbstractLiveEntityTest() { companion object { private const val REASON_SHUTDOWN = "The live entity mock is shut down" } - @Disabled inner class LiveEntityMock(kord: Kord) : AbstractLiveKordEntity(kord) { @@ -45,9 +41,11 @@ class LiveKordEntityTest : AbstractLiveEntityTest counter?.count() - is ReactionAddEvent -> shutDown(LiveCancellationException(event, REASON_SHUTDOWN)) + runTest { + when (event) { + is BanAddEvent -> counter?.count() + is ReactionAddEvent -> shutDown(LiveCancellationException(event, REASON_SHUTDOWN)) + } } } } @@ -58,6 +56,7 @@ class LiveKordEntityTest : AbstractLiveEntityTest { } assertTrue(job.isActive) @@ -75,18 +75,22 @@ class LiveKordEntityTest : AbstractLiveEntityTest { error("Never called") } diff --git a/core/src/test/kotlin/live/LiveMemberTest.kt b/core/src/commonTest/kotlin/live/LiveMemberTest.kt similarity index 86% rename from core/src/test/kotlin/live/LiveMemberTest.kt rename to core/src/commonTest/kotlin/live/LiveMemberTest.kt index bcb9fb5c2a59..5eabcb348989 100644 --- a/core/src/test/kotlin/live/LiveMemberTest.kt +++ b/core/src/commonTest/kotlin/live/LiveMemberTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional @@ -8,41 +8,28 @@ import dev.kord.core.entity.Member import dev.kord.core.event.guild.BanAddEvent import dev.kord.core.event.guild.GuildDeleteEvent import dev.kord.core.event.guild.MemberLeaveEvent -import dev.kord.core.live.LiveMember import dev.kord.core.live.exception.LiveCancellationException -import dev.kord.core.live.onUpdate +import dev.kord.core.randomId import dev.kord.gateway.GuildBanAdd import dev.kord.gateway.GuildDelete import dev.kord.gateway.GuildMemberRemove import dev.kord.gateway.GuildMemberUpdate -import equality.randomId import kotlinx.coroutines.job -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveMemberTest : AbstractLiveEntityTest() { - private lateinit var userId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - userId = randomId() - } + private val userId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveMember( Member( kord = kord, @@ -64,6 +51,7 @@ class LiveMemberTest : AbstractLiveEntityTest() { } @Test + @JsName("test1") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { @@ -91,13 +79,16 @@ class LiveMemberTest : AbstractLiveEntityTest() { } @Test + @JsName("test2") fun `Check onLeave is called when event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as MemberLeaveEvent assertEquals(userId, event.user.id) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(userId) { @@ -118,13 +109,16 @@ class LiveMemberTest : AbstractLiveEntityTest() { } @Test + @JsName("test3") fun `Check if live entity is completed when the member is banned`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as BanAddEvent assertEquals(userId, event.user.id) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(userId) { @@ -145,13 +139,16 @@ class LiveMemberTest : AbstractLiveEntityTest() { } @Test + @JsName("test4") fun `Check if live entity is completed when the guild is deleted`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as GuildDeleteEvent assertEquals(guildId, event.guildId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(guildId) { diff --git a/core/src/test/kotlin/live/LiveMessageTest.kt b/core/src/commonTest/kotlin/live/LiveMessageTest.kt similarity index 91% rename from core/src/test/kotlin/live/LiveMessageTest.kt rename to core/src/commonTest/kotlin/live/LiveMessageTest.kt index 0637cf7cc94d..02b1b92bea8b 100644 --- a/core/src/test/kotlin/live/LiveMessageTest.kt +++ b/core/src/commonTest/kotlin/live/LiveMessageTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.* import dev.kord.core.cache.data.MessageData @@ -9,41 +9,25 @@ import dev.kord.core.event.channel.ChannelDeleteEvent import dev.kord.core.event.guild.GuildDeleteEvent import dev.kord.core.event.message.MessageBulkDeleteEvent import dev.kord.core.event.message.MessageDeleteEvent -import dev.kord.core.live.* import dev.kord.core.live.exception.LiveCancellationException +import dev.kord.core.randomId import dev.kord.gateway.* -import equality.randomId import kotlinx.coroutines.job -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit -import kotlin.test.BeforeTest -import kotlin.test.Test -import kotlin.test.assertEquals -import kotlin.test.assertTrue - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +import kotlin.js.JsName +import kotlin.test.* + +@Ignore class LiveMessageTest : AbstractLiveEntityTest() { - private lateinit var messageId: Snowflake + private val messageId: Snowflake = randomId() - private lateinit var channelId: Snowflake + private val channelId: Snowflake = randomId() - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - messageId = randomId() - channelId = randomId() - } @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveMessage( guildId = guildId, message = Message( @@ -72,6 +56,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test1") fun `Check onReactionAdd is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -97,6 +82,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test2") fun `Check onReactionAdd with specific reaction is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -125,6 +111,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test3") fun `Check onReactionRemove is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -150,6 +137,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test4") fun `Check onReactionRemove with specific reaction is called when event is received`() { countdownContext(1) { val emojiExpected = ReactionEmoji.Unicode("\uD83D\uDC28") @@ -178,6 +166,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test5") fun `Check onReactionRemoveAll is called when event is received`() { countdownContext(1) { live.onReactionRemoveAll { @@ -198,6 +187,7 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test6") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { @@ -218,13 +208,16 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test7") fun `Check if live entity is completed when event the message delete event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as MessageDeleteEvent assertEquals(messageId, event.messageId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(messageId) { @@ -240,13 +233,16 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test8") fun `Check if live entity is completed when event the bulk delete event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as MessageBulkDeleteEvent assertTrue { messageId in event.messageIds } - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(messageId) { @@ -262,13 +258,16 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test9") fun `Check if live entity is completed when event the channel delete event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as ChannelDeleteEvent assertEquals(channelId, event.channel.id) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(channelId) { @@ -284,13 +283,16 @@ class LiveMessageTest : AbstractLiveEntityTest() { } @Test + @JsName("test10") fun `Check if live entity is completed when event the guild delete event is received`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as GuildDeleteEvent assertEquals(guildId, event.guildId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(guildId) { diff --git a/core/src/test/kotlin/live/LiveRoleTest.kt b/core/src/commonTest/kotlin/live/LiveRoleTest.kt similarity index 85% rename from core/src/test/kotlin/live/LiveRoleTest.kt rename to core/src/commonTest/kotlin/live/LiveRoleTest.kt index bdbec2e4cf6a..3f19e64bf214 100644 --- a/core/src/test/kotlin/live/LiveRoleTest.kt +++ b/core/src/commonTest/kotlin/live/LiveRoleTest.kt @@ -1,4 +1,4 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional @@ -6,35 +6,24 @@ import dev.kord.core.cache.data.RoleData import dev.kord.core.entity.Role import dev.kord.core.event.guild.GuildDeleteEvent import dev.kord.core.event.role.RoleDeleteEvent -import dev.kord.core.live.LiveRole import dev.kord.core.live.exception.LiveCancellationException -import dev.kord.core.live.onUpdate +import dev.kord.core.randomId import dev.kord.gateway.GuildDelete import dev.kord.gateway.GuildRoleDelete import dev.kord.gateway.GuildRoleUpdate -import equality.randomId import kotlinx.coroutines.job -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveRoleTest : AbstractLiveEntityTest() { - private lateinit var roleId: Snowflake + private val roleId: Snowflake = randomId() - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - roleId = randomId() - } @BeforeTest fun onBefore() { @@ -59,6 +48,7 @@ class LiveRoleTest : AbstractLiveEntityTest() { } @Test + @JsName("test1") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { @@ -90,13 +80,16 @@ class LiveRoleTest : AbstractLiveEntityTest() { } @Test + @JsName("test2") fun `Check if live entity is completed when the role is deleted`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as RoleDeleteEvent assertEquals(roleId, event.roleId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(roleId) { @@ -112,13 +105,16 @@ class LiveRoleTest : AbstractLiveEntityTest() { } @Test + @JsName("test3") fun `Check if live entity is completed when the guild is deleted`() { countdownContext(1) { live.coroutineContext.job.invokeOnCompletion { it as LiveCancellationException val event = it.event as GuildDeleteEvent assertEquals(guildId, event.guildId) - count() + runTest { + count() + } } sendEventValidAndRandomIdCheckLiveActive(guildId) { diff --git a/core/src/test/kotlin/live/LiveUserTest.kt b/core/src/commonTest/kotlin/live/LiveUserTest.kt similarity index 65% rename from core/src/test/kotlin/live/LiveUserTest.kt rename to core/src/commonTest/kotlin/live/LiveUserTest.kt index a204922b8054..4783c4bc4130 100644 --- a/core/src/test/kotlin/live/LiveUserTest.kt +++ b/core/src/commonTest/kotlin/live/LiveUserTest.kt @@ -1,38 +1,25 @@ -package live +package dev.kord.core.live import dev.kord.common.entity.DiscordUser import dev.kord.common.entity.Snowflake import dev.kord.core.cache.data.UserData import dev.kord.core.entity.User -import dev.kord.core.live.LiveUser -import dev.kord.core.live.onUpdate +import dev.kord.core.randomId import dev.kord.gateway.UserUpdate -import equality.randomId -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveUserTest : AbstractLiveEntityTest() { - private lateinit var userId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - userId = randomId() - } + private val userId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveUser( user = User( kord = kord, @@ -46,6 +33,7 @@ class LiveUserTest : AbstractLiveEntityTest() { } @Test + @JsName("test1") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/live/channel/LiveCategoryTest.kt b/core/src/commonTest/kotlin/live/channel/LiveCategoryTest.kt similarity index 66% rename from core/src/test/kotlin/live/channel/LiveCategoryTest.kt rename to core/src/commonTest/kotlin/live/channel/LiveCategoryTest.kt index a082dc863803..afbb9036f769 100644 --- a/core/src/test/kotlin/live/channel/LiveCategoryTest.kt +++ b/core/src/commonTest/kotlin/live/channel/LiveCategoryTest.kt @@ -1,4 +1,4 @@ -package live.channel +package dev.kord.core.live.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.DiscordChannel @@ -6,35 +6,22 @@ import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.channel.Category -import dev.kord.core.live.channel.LiveCategory -import dev.kord.core.live.channel.onUpdate +import dev.kord.core.randomId import dev.kord.gateway.ChannelUpdate -import equality.randomId -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveCategoryTest : LiveChannelTest() { - override lateinit var channelId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - channelId = randomId() - } + override val channelId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveCategory( Category( kord = kord, @@ -48,6 +35,7 @@ class LiveCategoryTest : LiveChannelTest() { } @Test + @JsName("testOnUpdate") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/live/channel/LiveChannelTest.kt b/core/src/commonTest/kotlin/live/channel/LiveChannelTest.kt similarity index 85% rename from core/src/test/kotlin/live/channel/LiveChannelTest.kt rename to core/src/commonTest/kotlin/live/channel/LiveChannelTest.kt index ecb006668ffd..2fc1e617b045 100644 --- a/core/src/test/kotlin/live/channel/LiveChannelTest.kt +++ b/core/src/commonTest/kotlin/live/channel/LiveChannelTest.kt @@ -1,4 +1,4 @@ -package live.channel +package dev.kord.core.live.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.DiscordChannel @@ -8,31 +8,27 @@ import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.channel.* import dev.kord.core.event.channel.ChannelDeleteEvent import dev.kord.core.event.guild.GuildDeleteEvent -import dev.kord.core.live.channel.* +import dev.kord.core.live.AbstractLiveEntityTest import dev.kord.core.live.exception.LiveCancellationException +import dev.kord.core.randomId import dev.kord.gateway.ChannelDelete import dev.kord.gateway.GuildDelete -import equality.randomId import kotlinx.coroutines.job -import kotlinx.coroutines.runBlocking -import live.AbstractLiveEntityTest -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.reflect.KClass +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore abstract class LiveChannelTest : AbstractLiveEntityTest() { protected abstract val channelId: Snowflake @Test - fun `Check type of live entity corresponds to the channel type`() = runBlocking { + @JsName("test41") + fun `Check type of live entity corresponds to the channel type`() = runTest { val data = ChannelData( id = randomId(), type = ChannelType.DM @@ -49,13 +45,16 @@ abstract class LiveChannelTest : AbstractLiveEntityTest : AbstractLiveEntityTest() { - override lateinit var channelId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - channelId = randomId() - } + override val channelId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveDmChannel( DmChannel( kord = kord, @@ -48,6 +35,7 @@ class LiveDmChannelTest : LiveChannelTest() { } @Test + @JsName("test31") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/live/channel/LiveGuildChannelTest.kt b/core/src/commonTest/kotlin/live/channel/LiveGuildChannelTest.kt similarity index 73% rename from core/src/test/kotlin/live/channel/LiveGuildChannelTest.kt rename to core/src/commonTest/kotlin/live/channel/LiveGuildChannelTest.kt index 6235f15d2da4..1fe0e03905bc 100644 --- a/core/src/test/kotlin/live/channel/LiveGuildChannelTest.kt +++ b/core/src/commonTest/kotlin/live/channel/LiveGuildChannelTest.kt @@ -1,4 +1,4 @@ -package live.channel +package dev.kord.core.live.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.DiscordChannel @@ -7,25 +7,18 @@ import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.Kord import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.channel.TopGuildMessageChannel -import dev.kord.core.live.channel.LiveGuildChannel -import dev.kord.core.live.channel.onUpdate +import dev.kord.core.randomId import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.gateway.ChannelUpdate -import equality.randomId -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveGuildChannelTest : LiveChannelTest() { inner class GuildChannelMock( @@ -38,16 +31,10 @@ class LiveGuildChannelTest : LiveChannelTest() { } } - override lateinit var channelId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - channelId = randomId() - } + override val channelId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveGuildChannel( GuildChannelMock( kord = kord, @@ -61,6 +48,7 @@ class LiveGuildChannelTest : LiveChannelTest() { } @Test + @JsName("test11") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/live/channel/LiveGuildTextTest.kt b/core/src/commonTest/kotlin/live/channel/LiveGuildTextTest.kt similarity index 72% rename from core/src/test/kotlin/live/channel/LiveGuildTextTest.kt rename to core/src/commonTest/kotlin/live/channel/LiveGuildTextTest.kt index cb384ce02b2e..5d34889f54c0 100644 --- a/core/src/test/kotlin/live/channel/LiveGuildTextTest.kt +++ b/core/src/commonTest/kotlin/live/channel/LiveGuildTextTest.kt @@ -1,4 +1,4 @@ -package live.channel +package dev.kord.core.live.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.DiscordChannel @@ -7,25 +7,18 @@ import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.Kord import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.channel.TopGuildChannel -import dev.kord.core.live.channel.LiveGuildChannel -import dev.kord.core.live.channel.onUpdate +import dev.kord.core.randomId import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.gateway.ChannelUpdate -import equality.randomId -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveGuildTextTest : LiveChannelTest() { inner class GuildChannelMock( @@ -38,16 +31,10 @@ class LiveGuildTextTest : LiveChannelTest() { } } - override lateinit var channelId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - channelId = randomId() - } + override val channelId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveGuildChannel( GuildChannelMock( kord = kord, @@ -61,6 +48,7 @@ class LiveGuildTextTest : LiveChannelTest() { } @Test + @JsName("testOnUpdate") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/live/channel/LiveVoiceChannelTest.kt b/core/src/commonTest/kotlin/live/channel/LiveVoiceChannelTest.kt similarity index 66% rename from core/src/test/kotlin/live/channel/LiveVoiceChannelTest.kt rename to core/src/commonTest/kotlin/live/channel/LiveVoiceChannelTest.kt index 993e50e4c541..72b2913edc59 100644 --- a/core/src/test/kotlin/live/channel/LiveVoiceChannelTest.kt +++ b/core/src/commonTest/kotlin/live/channel/LiveVoiceChannelTest.kt @@ -1,4 +1,4 @@ -package live.channel +package dev.kord.core.live.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.DiscordChannel @@ -6,35 +6,22 @@ import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData import dev.kord.core.entity.channel.VoiceChannel -import dev.kord.core.live.channel.LiveVoiceChannel -import dev.kord.core.live.channel.onUpdate +import dev.kord.core.randomId import dev.kord.gateway.ChannelUpdate -import equality.randomId -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.BeforeAll -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.TestInstance -import org.junit.jupiter.api.Timeout -import java.util.concurrent.TimeUnit +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.BeforeTest +import kotlin.test.Ignore import kotlin.test.Test import kotlin.test.assertEquals -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@Timeout(value = 5, unit = TimeUnit.SECONDS) -@Disabled +@Ignore class LiveVoiceChannelTest : LiveChannelTest() { - override lateinit var channelId: Snowflake - - @BeforeAll - override fun onBeforeAll() { - super.onBeforeAll() - channelId = randomId() - } + override val channelId: Snowflake = randomId() @BeforeTest - fun onBefore() = runBlocking { + fun onBefore() = runTest { live = LiveVoiceChannel( VoiceChannel( kord = kord, @@ -48,6 +35,7 @@ class LiveVoiceChannelTest : LiveChannelTest() { } @Test + @JsName("test21") fun `Check onUpdate is called when event is received`() { countdownContext(1) { live.onUpdate { diff --git a/core/src/test/kotlin/performance/KordEventDropTest.kt b/core/src/commonTest/kotlin/performance/KordEventDropTest.kt similarity index 79% rename from core/src/test/kotlin/performance/KordEventDropTest.kt rename to core/src/commonTest/kotlin/performance/KordEventDropTest.kt index 6d35fe457ba1..7f6aeb98e49c 100644 --- a/core/src/test/kotlin/performance/KordEventDropTest.kt +++ b/core/src/commonTest/kotlin/performance/KordEventDropTest.kt @@ -4,7 +4,6 @@ import dev.kord.cache.api.DataCache import dev.kord.common.entity.* import dev.kord.core.ClientResources import dev.kord.core.Kord -import dev.kord.core.event.guild.GuildCreateEvent import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor import dev.kord.core.on @@ -14,22 +13,23 @@ import dev.kord.gateway.builder.Shards import dev.kord.rest.request.KtorRequestHandler import dev.kord.rest.service.RestClient import io.ktor.client.* +import kotlinx.atomicfu.atomic +import kotlinx.coroutines.CompletableDeferred import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.SupervisorJob import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.withTimeout +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Clock -import java.util.concurrent.CountDownLatch -import java.util.concurrent.atomic.AtomicInteger import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds class KordEventDropTest { @@ -63,7 +63,8 @@ class KordEventDropTest { ) @Test - fun `hammering the gateway does not drop core events`() = runBlocking { + @JsName("test1") + fun `hammering the gateway does not drop core events`() = runTest { val amount = 1_000 val event = GuildCreate( @@ -97,21 +98,27 @@ class KordEventDropTest { ), 0 ) - val counter = AtomicInteger(0) - val countdown = CountDownLatch(amount) - kord.on { - counter.incrementAndGet() - countdown.countDown() + val counter = object { + private val counter = atomic(0) + fun incrementAndGet() = counter.incrementAndGet() + val value by counter } + val completion = CompletableDeferred() - repeat(amount) { - SpammyGateway.events.emit(event) + kord.on { + if (counter.incrementAndGet() == amount) completion.complete(Unit) } - withTimeout(1.minutes.inWholeMilliseconds) { - countdown.await() + launch { + // wait until we are actually listening + SpammyGateway.events.subscriptionCount.first { it == 1 } + + repeat(amount) { + SpammyGateway.events.emit(event) + } } - assertEquals(amount, counter.get()) - } + completion.await() + assertEquals(amount, counter.value) + } } diff --git a/core/src/test/kotlin/regression/ReactionEmojiTest.kt b/core/src/commonTest/kotlin/regression/ReactionEmojiTest.kt similarity index 80% rename from core/src/test/kotlin/regression/ReactionEmojiTest.kt rename to core/src/commonTest/kotlin/regression/ReactionEmojiTest.kt index a32d940a0d3a..c1c1c52f0b91 100644 --- a/core/src/test/kotlin/regression/ReactionEmojiTest.kt +++ b/core/src/commonTest/kotlin/regression/ReactionEmojiTest.kt @@ -1,12 +1,14 @@ -package regression +package dev.kord.core.regression import dev.kord.common.entity.Snowflake import dev.kord.core.entity.ReactionEmoji +import kotlin.js.JsName import kotlin.test.Test class ReactionEmojiTest { @Test + @JsName("test1") fun `getting the id of a reaction emoji doesn't cause a castException`() { val emoji = ReactionEmoji.Custom(Snowflake(0u), "test", false) emoji.id diff --git a/core/src/test/kotlin/supplier/CacheEntitySupplierTest.kt b/core/src/commonTest/kotlin/supplier/CacheEntitySupplierTest.kt similarity index 88% rename from core/src/test/kotlin/supplier/CacheEntitySupplierTest.kt rename to core/src/commonTest/kotlin/supplier/CacheEntitySupplierTest.kt index c609bb23ac41..5b54c6ffe540 100644 --- a/core/src/test/kotlin/supplier/CacheEntitySupplierTest.kt +++ b/core/src/commonTest/kotlin/supplier/CacheEntitySupplierTest.kt @@ -1,4 +1,4 @@ -package supplier +package dev.kord.core.supplier import dev.kord.common.annotation.KordUnsafe import dev.kord.common.entity.Snowflake @@ -7,7 +7,6 @@ import dev.kord.core.Kord import dev.kord.core.cache.KordCacheBuilder import dev.kord.core.gateway.DefaultMasterGateway import dev.kord.core.gateway.handler.DefaultGatewayEventInterceptor -import dev.kord.core.supplier.EntitySupplyStrategy import dev.kord.gateway.Gateway import dev.kord.gateway.builder.Shards import dev.kord.rest.request.KtorRequestHandler @@ -16,14 +15,16 @@ import io.ktor.client.* import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.toList -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Test +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName +import kotlin.test.Test internal class CacheEntitySupplierTest { @Test @OptIn(KordUnsafe::class) - fun `cache does not throw when accessing unregistered entities`(): Unit = runBlocking { + @JsName("test1") + fun `cache does not throw when accessing unregistered entities`() = runTest { val kord = Kord( ClientResources("", Snowflake(0u), Shards(0), maxConcurrency = 1, HttpClient(), EntitySupplyStrategy.cache), KordCacheBuilder().build(), @@ -37,5 +38,4 @@ internal class CacheEntitySupplierTest { kord.unsafe.guild(Snowflake(0u)).regions.toList() } - } diff --git a/core/src/jsMain/kotlin/KordBuilder.kt b/core/src/jsMain/kotlin/KordBuilder.kt new file mode 100644 index 000000000000..a3d196befb43 --- /dev/null +++ b/core/src/jsMain/kotlin/KordBuilder.kt @@ -0,0 +1,3 @@ +package dev.kord.core.builder.kord + +public actual class KordBuilder actual constructor(token: String) : BaseKordBuilder(token) diff --git a/core/src/jvmMain/kotlin/builder/kord/KordBuilder.kt b/core/src/jvmMain/kotlin/builder/kord/KordBuilder.kt new file mode 100644 index 000000000000..949249cfb12f --- /dev/null +++ b/core/src/jvmMain/kotlin/builder/kord/KordBuilder.kt @@ -0,0 +1,26 @@ +package dev.kord.core.builder.kord + +import dev.kord.core.Kord +import dev.kord.gateway.Gateway +import kotlinx.coroutines.runBlocking +import kotlin.concurrent.thread + +public actual class KordBuilder actual constructor(token: String) : BaseKordBuilder(token) { + /** + * Enable adding a [Runtime.addShutdownHook] to log out of the [Gateway] when the process is killed. + */ + public var enableShutdownHook: Boolean = true + + override suspend fun build(): Kord { + val kord = buildBase() + if (enableShutdownHook) { + Runtime.getRuntime().addShutdownHook(thread(false) { + runBlocking { + kord.gateway.detachAll() + } + }) + } + + return kord + } +} diff --git a/core/src/jvmMain/kotlin/cache/KordCacheBuilder.kt b/core/src/jvmMain/kotlin/cache/KordCacheBuilder.kt new file mode 100644 index 000000000000..97dcaa6f7cb8 --- /dev/null +++ b/core/src/jvmMain/kotlin/cache/KordCacheBuilder.kt @@ -0,0 +1,15 @@ +package dev.kord.core.cache + +import dev.kord.cache.api.DataEntryCache +import dev.kord.cache.map.MapLikeCollection +import dev.kord.cache.map.internal.MapEntryCache +import dev.kord.cache.map.lruLinkedHashMap + +/** + * A Generator creating [DataEntryCaches][DataEntryCache] with a maximum [size], removing items on last insertion. + * Shortcut for [lruLinkedHashMap]. + */ +@Suppress("UnusedReceiverParameter") // used for scoping +public fun KordCacheBuilder.lruCache(size: Int = 100): Generator = { cache, description -> + MapEntryCache(cache, description, MapLikeCollection.lruLinkedHashMap(size)) +} diff --git a/core/src/test/kotlin/Util.kt b/core/src/jvmTest/kotlin/MockKord.kt similarity index 93% rename from core/src/test/kotlin/Util.kt rename to core/src/jvmTest/kotlin/MockKord.kt index 108c9d99c1e2..caa1081fb399 100644 --- a/core/src/test/kotlin/Util.kt +++ b/core/src/jvmTest/kotlin/MockKord.kt @@ -1,4 +1,5 @@ -import dev.kord.core.Kord +package dev.kord.core + import dev.kord.core.supplier.EntitySupplier import dev.kord.core.supplier.EntitySupplyStrategy import io.mockk.every @@ -16,4 +17,4 @@ fun mockKord(): Kord = every { defaultStrategy } returns strategy } every { defaultSupplier } returns supplier - } \ No newline at end of file + } diff --git a/core/src/test/kotlin/behavior/GuildBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/GuildBehaviorTest.kt similarity index 68% rename from core/src/test/kotlin/behavior/GuildBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/GuildBehaviorTest.kt index 7b08eaa398f8..b53ec1d494e5 100644 --- a/core/src/test/kotlin/behavior/GuildBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/GuildBehaviorTest.kt @@ -1,9 +1,9 @@ package dev.kord.core.behavior -import equality.EntityEqualityTest -import mockKord +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord internal class GuildBehaviorTest: EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() GuildBehavior(it, kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/MemberBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/MemberBehaviorTest.kt similarity index 73% rename from core/src/test/kotlin/behavior/MemberBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/MemberBehaviorTest.kt index bf5560613b08..372d8ad13ae5 100644 --- a/core/src/test/kotlin/behavior/MemberBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/MemberBehaviorTest.kt @@ -1,9 +1,9 @@ package dev.kord.core.behavior -import equality.GuildEntityEqualityTest -import mockKord +import dev.kord.core.equality.GuildEntityEqualityTest +import dev.kord.core.mockKord internal class MemberBehaviorTest : GuildEntityEqualityTest by GuildEntityEqualityTest({ id, guildId -> val kord = mockKord() MemberBehavior(guildId = guildId, id = id, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/MessageBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/MessageBehaviorTest.kt similarity index 75% rename from core/src/test/kotlin/behavior/MessageBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/MessageBehaviorTest.kt index ec969a237df7..6bb2cd6a1779 100644 --- a/core/src/test/kotlin/behavior/MessageBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/MessageBehaviorTest.kt @@ -1,8 +1,8 @@ package dev.kord.core.behavior import dev.kord.common.entity.Snowflake -import equality.EntityEqualityTest -import mockKord +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord internal class MessageBehaviorTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() diff --git a/core/src/test/kotlin/behavior/RoleBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/RoleBehaviorTest.kt similarity index 87% rename from core/src/test/kotlin/behavior/RoleBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/RoleBehaviorTest.kt index 08d1f328b8dd..7ee910d59728 100644 --- a/core/src/test/kotlin/behavior/RoleBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/RoleBehaviorTest.kt @@ -1,8 +1,8 @@ package dev.kord.core.behavior import dev.kord.common.entity.Snowflake -import equality.GuildEntityEqualityTest -import mockKord +import dev.kord.core.equality.GuildEntityEqualityTest +import dev.kord.core.mockKord import org.junit.jupiter.api.Test import kotlin.test.assertEquals diff --git a/core/src/test/kotlin/behavior/UserBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/UserBehaviorTest.kt similarity index 68% rename from core/src/test/kotlin/behavior/UserBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/UserBehaviorTest.kt index 0d0385d439d6..2f49a7df24f9 100644 --- a/core/src/test/kotlin/behavior/UserBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/UserBehaviorTest.kt @@ -1,9 +1,9 @@ package dev.kord.core.behavior -import equality.EntityEqualityTest -import mockKord +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord internal class UserBehaviorTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() UserBehavior(it, kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/WebhookBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/WebhookBehaviorTest.kt similarity index 69% rename from core/src/test/kotlin/behavior/WebhookBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/WebhookBehaviorTest.kt index d7f9735f8f8a..6f252f3bb0f9 100644 --- a/core/src/test/kotlin/behavior/WebhookBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/WebhookBehaviorTest.kt @@ -1,9 +1,9 @@ package dev.kord.core.behavior -import equality.EntityEqualityTest -import mockKord +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord internal class WebhookBehaviorTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() WebhookBehavior(it, kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/CategoryBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/CategoryBehaviorTest.kt similarity index 77% rename from core/src/test/kotlin/behavior/channel/CategoryBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/CategoryBehaviorTest.kt index 35a718cef4da..1e7fb7664233 100644 --- a/core/src/test/kotlin/behavior/channel/CategoryBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/CategoryBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class CategoryBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() CategoryBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/ChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/ChannelBehaviorTest.kt similarity index 76% rename from core/src/test/kotlin/behavior/channel/ChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/ChannelBehaviorTest.kt index 6c96164e114d..7bb991b8a14e 100644 --- a/core/src/test/kotlin/behavior/channel/ChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/ChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.ChannelEqualityTest -import mockKord +import dev.kord.core.equality.ChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class ChannelBehaviorTest : ChannelEqualityTest by ChannelEqualityTest({ id -> val kord = mockKord() ChannelBehavior(id = id, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/GuildChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/GuildChannelBehaviorTest.kt similarity index 78% rename from core/src/test/kotlin/behavior/channel/GuildChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/GuildChannelBehaviorTest.kt index 6b79846e0e71..652d7293045d 100644 --- a/core/src/test/kotlin/behavior/channel/GuildChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/GuildChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class GuildChannelBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() TopGuildChannelBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt similarity index 79% rename from core/src/test/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt index f9e27d5613df..26a7bb1c9839 100644 --- a/core/src/test/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/GuildMessageChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class GuildMessageChannelBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() TopGuildMessageChannelBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/MessageChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/MessageChannelBehaviorTest.kt similarity index 77% rename from core/src/test/kotlin/behavior/channel/MessageChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/MessageChannelBehaviorTest.kt index 66be7a6f275e..93bd39ffddb0 100644 --- a/core/src/test/kotlin/behavior/channel/MessageChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/MessageChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.ChannelEqualityTest -import mockKord +import dev.kord.core.equality.ChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class MessageChannelBehaviorTest : ChannelEqualityTest by ChannelEqualityTest({ id -> val kord = mockKord() MessageChannelBehavior(id = id, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/NewsChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/NewsChannelBehaviorTest.kt similarity index 78% rename from core/src/test/kotlin/behavior/channel/NewsChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/NewsChannelBehaviorTest.kt index d81b4bd31b8e..4f7265ac10cf 100644 --- a/core/src/test/kotlin/behavior/channel/NewsChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/NewsChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class NewsChannelBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() NewsChannelBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/TextChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/TextChannelBehaviorTest.kt similarity index 78% rename from core/src/test/kotlin/behavior/channel/TextChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/TextChannelBehaviorTest.kt index f15b0b561c5d..7422915dbed8 100644 --- a/core/src/test/kotlin/behavior/channel/TextChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/TextChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class TextChannelBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() TextChannelBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt b/core/src/jvmTest/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt similarity index 78% rename from core/src/test/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt rename to core/src/jvmTest/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt index cb8fd2f61269..43c2359d6a80 100644 --- a/core/src/test/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt +++ b/core/src/jvmTest/kotlin/behavior/channel/VoiceChannelBehaviorTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.behavior.channel -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class VoiceChannelBehaviorTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() VoiceChannelBehavior(id = id, guildId = guildId, kord = kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/ApplicationTest.kt b/core/src/jvmTest/kotlin/entity/ApplicationTest.kt similarity index 74% rename from core/src/test/kotlin/entity/ApplicationTest.kt rename to core/src/jvmTest/kotlin/entity/ApplicationTest.kt index 55497b6fd1c6..b707b1ead7c3 100644 --- a/core/src/test/kotlin/entity/ApplicationTest.kt +++ b/core/src/jvmTest/kotlin/entity/ApplicationTest.kt @@ -1,11 +1,10 @@ -package entity +package dev.kord.core.entity import dev.kord.core.cache.data.ApplicationData -import dev.kord.core.entity.Application -import equality.EntityEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class ApplicationTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() diff --git a/core/src/test/kotlin/entity/AttachmentTest.kt b/core/src/jvmTest/kotlin/entity/AttachmentTest.kt similarity index 81% rename from core/src/test/kotlin/entity/AttachmentTest.kt rename to core/src/jvmTest/kotlin/entity/AttachmentTest.kt index c4fb62adac69..d228444074e3 100644 --- a/core/src/test/kotlin/entity/AttachmentTest.kt +++ b/core/src/jvmTest/kotlin/entity/AttachmentTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.entity import dev.kord.core.cache.data.AttachmentData -import equality.EntityEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class AttachmentTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() diff --git a/core/src/test/kotlin/entity/GuildEmojiTest.kt b/core/src/jvmTest/kotlin/entity/GuildEmojiTest.kt similarity index 81% rename from core/src/test/kotlin/entity/GuildEmojiTest.kt rename to core/src/jvmTest/kotlin/entity/GuildEmojiTest.kt index 6a7b997c58bf..77e021a89cd6 100644 --- a/core/src/test/kotlin/entity/GuildEmojiTest.kt +++ b/core/src/jvmTest/kotlin/entity/GuildEmojiTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.entity import dev.kord.core.cache.data.EmojiData -import equality.GuildEntityEqualityTest +import dev.kord.core.equality.GuildEntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class GuildEmojiTest : GuildEntityEqualityTest by GuildEntityEqualityTest({ id, guildId -> val kord = mockKord() @@ -12,4 +12,4 @@ internal class GuildEmojiTest : GuildEntityEqualityTest by GuildEnti every { data.id } returns id every { data.guildId } returns guildId GuildEmoji(data, kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/GuildTest.kt b/core/src/jvmTest/kotlin/entity/GuildTest.kt similarity index 77% rename from core/src/test/kotlin/entity/GuildTest.kt rename to core/src/jvmTest/kotlin/entity/GuildTest.kt index 03fa31e04b31..bcb9637033ac 100644 --- a/core/src/test/kotlin/entity/GuildTest.kt +++ b/core/src/jvmTest/kotlin/entity/GuildTest.kt @@ -2,11 +2,11 @@ package dev.kord.core.entity import dev.kord.core.behavior.GuildBehavior import dev.kord.core.cache.data.GuildData -import equality.BehaviorEqualityTest -import equality.EntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class GuildTest: EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() @@ -15,4 +15,4 @@ internal class GuildTest: EntityEqualityTest by EntityEqualityTest({ Guild(data, kord) }), BehaviorEqualityTest { override fun Guild.behavior(): KordEntity = GuildBehavior(id, kord) -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/IntegrationTest.kt b/core/src/jvmTest/kotlin/entity/IntegrationTest.kt similarity index 82% rename from core/src/test/kotlin/entity/IntegrationTest.kt rename to core/src/jvmTest/kotlin/entity/IntegrationTest.kt index ae5a0a1f9e30..37dd58a08626 100644 --- a/core/src/test/kotlin/entity/IntegrationTest.kt +++ b/core/src/jvmTest/kotlin/entity/IntegrationTest.kt @@ -1,10 +1,10 @@ package dev.kord.core.entity import dev.kord.core.cache.data.IntegrationData -import equality.GuildEntityEqualityTest +import dev.kord.core.equality.GuildEntityEqualityTest import io.mockk.every import io.mockk.mockk -import mockKord +import dev.kord.core.mockKord internal class IntegrationTest : GuildEntityEqualityTest by GuildEntityEqualityTest ({ id, guildId -> val kord = mockKord() @@ -12,4 +12,4 @@ internal class IntegrationTest : GuildEntityEqualityTest by GuildEn every { data.id } returns id every { data.guildId } returns guildId Integration(data, kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/MemberTest.kt b/core/src/jvmTest/kotlin/entity/MemberTest.kt similarity index 90% rename from core/src/test/kotlin/entity/MemberTest.kt rename to core/src/jvmTest/kotlin/entity/MemberTest.kt index 4b14d0917cab..6fff9f80dbd4 100644 --- a/core/src/test/kotlin/entity/MemberTest.kt +++ b/core/src/jvmTest/kotlin/entity/MemberTest.kt @@ -4,11 +4,11 @@ import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.MemberBehavior import dev.kord.core.cache.data.MemberData import dev.kord.core.cache.data.UserData -import equality.BehaviorEqualityTest -import equality.GuildEntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.GuildEntityEqualityTest import io.mockk.every import io.mockk.mockk -import mockKord +import dev.kord.core.mockKord import org.junit.jupiter.api.Test import kotlin.test.assertEquals diff --git a/core/src/test/kotlin/entity/MessageTest.kt b/core/src/jvmTest/kotlin/entity/MessageTest.kt similarity index 80% rename from core/src/test/kotlin/entity/MessageTest.kt rename to core/src/jvmTest/kotlin/entity/MessageTest.kt index 5ea9f3af7094..203bb63a84f9 100644 --- a/core/src/test/kotlin/entity/MessageTest.kt +++ b/core/src/jvmTest/kotlin/entity/MessageTest.kt @@ -2,11 +2,11 @@ package dev.kord.core.entity import dev.kord.core.behavior.MessageBehavior import dev.kord.core.cache.data.MessageData -import equality.BehaviorEqualityTest -import equality.EntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class MessageTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() @@ -16,4 +16,4 @@ internal class MessageTest : EntityEqualityTest by EntityEqualityTest({ Message(data, kord) }), BehaviorEqualityTest { override fun Message.behavior(): KordEntity = MessageBehavior(messageId = id, channelId = id, kord = kord) -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/RoleTest.kt b/core/src/jvmTest/kotlin/entity/RoleTest.kt similarity index 83% rename from core/src/test/kotlin/entity/RoleTest.kt rename to core/src/jvmTest/kotlin/entity/RoleTest.kt index ee3dcc6df5ab..f18c08de0a8a 100644 --- a/core/src/test/kotlin/entity/RoleTest.kt +++ b/core/src/jvmTest/kotlin/entity/RoleTest.kt @@ -3,11 +3,11 @@ package dev.kord.core.entity import dev.kord.common.entity.optional.Optional import dev.kord.core.behavior.RoleBehavior import dev.kord.core.cache.data.RoleData -import equality.BehaviorEqualityTest -import equality.GuildEntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.GuildEntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class RoleTest : GuildEntityEqualityTest by GuildEntityEqualityTest({ id, guildId -> val kord = mockKord() @@ -19,4 +19,4 @@ internal class RoleTest : GuildEntityEqualityTest by GuildEntityEqualityTe Role(data, kord) }), BehaviorEqualityTest { override fun Role.behavior(): KordEntity = RoleBehavior(guildId = guildId, id = id, kord = kord) -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/UserTest.kt b/core/src/jvmTest/kotlin/entity/UserTest.kt similarity index 77% rename from core/src/test/kotlin/entity/UserTest.kt rename to core/src/jvmTest/kotlin/entity/UserTest.kt index 4b53357739e5..27f74cfab2c2 100644 --- a/core/src/test/kotlin/entity/UserTest.kt +++ b/core/src/jvmTest/kotlin/entity/UserTest.kt @@ -2,11 +2,11 @@ package dev.kord.core.entity import dev.kord.core.behavior.UserBehavior import dev.kord.core.cache.data.UserData -import equality.BehaviorEqualityTest -import equality.EntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class UserTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() @@ -15,4 +15,4 @@ internal class UserTest : EntityEqualityTest by EntityEqualityTest({ User(data, kord) }), BehaviorEqualityTest { override fun User.behavior(): KordEntity = UserBehavior(id = id, kord = kord) -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/WebhookTest.kt b/core/src/jvmTest/kotlin/entity/WebhookTest.kt similarity index 78% rename from core/src/test/kotlin/entity/WebhookTest.kt rename to core/src/jvmTest/kotlin/entity/WebhookTest.kt index 076bc5d051e8..3b16ee317d3b 100644 --- a/core/src/test/kotlin/entity/WebhookTest.kt +++ b/core/src/jvmTest/kotlin/entity/WebhookTest.kt @@ -2,11 +2,11 @@ package dev.kord.core.entity import dev.kord.core.behavior.WebhookBehavior import dev.kord.core.cache.data.WebhookData -import equality.BehaviorEqualityTest -import equality.EntityEqualityTest +import dev.kord.core.equality.BehaviorEqualityTest +import dev.kord.core.equality.EntityEqualityTest +import dev.kord.core.mockKord import io.mockk.every import io.mockk.mockk -import mockKord internal class WebhookTest : EntityEqualityTest by EntityEqualityTest({ val kord = mockKord() @@ -15,4 +15,4 @@ internal class WebhookTest : EntityEqualityTest by EntityEqualityTest({ Webhook(data, kord) }), BehaviorEqualityTest { override fun Webhook.behavior(): KordEntity = WebhookBehavior(id = id, kord = kord) -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/channel/CategoryTest.kt b/core/src/jvmTest/kotlin/entity/channel/CategoryTest.kt similarity index 84% rename from core/src/test/kotlin/entity/channel/CategoryTest.kt rename to core/src/jvmTest/kotlin/entity/channel/CategoryTest.kt index 79d612a62d9f..d31ba0f5d54a 100644 --- a/core/src/test/kotlin/entity/channel/CategoryTest.kt +++ b/core/src/jvmTest/kotlin/entity/channel/CategoryTest.kt @@ -3,8 +3,8 @@ package dev.kord.core.entity.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class CategoryTest : GuildChannelEqualityTest by GuildChannelEqualityTest ({ id, guildId -> @@ -12,4 +12,4 @@ internal class CategoryTest : GuildChannelEqualityTest by GuildChannel Category(ChannelData(id, guildId = guildId.optionalSnowflake(), type = ChannelType.GuildCategory), kord) }) { -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/entity/channel/DmChannelTest.kt b/core/src/jvmTest/kotlin/entity/channel/DmChannelTest.kt similarity index 78% rename from core/src/test/kotlin/entity/channel/DmChannelTest.kt rename to core/src/jvmTest/kotlin/entity/channel/DmChannelTest.kt index d184b87a131a..39276dc0a733 100644 --- a/core/src/test/kotlin/entity/channel/DmChannelTest.kt +++ b/core/src/jvmTest/kotlin/entity/channel/DmChannelTest.kt @@ -2,10 +2,10 @@ package dev.kord.core.entity.channel import dev.kord.common.entity.ChannelType import dev.kord.core.cache.data.ChannelData -import equality.ChannelEqualityTest -import mockKord +import dev.kord.core.equality.ChannelEqualityTest +import dev.kord.core.mockKord internal class DmChannelTest: ChannelEqualityTest by ChannelEqualityTest ({ id -> val kord = mockKord() DmChannel(ChannelData(id, type = ChannelType.DM), kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/channel/NewsChannelTest.kt b/core/src/jvmTest/kotlin/entity/channel/NewsChannelTest.kt similarity index 84% rename from core/src/test/kotlin/entity/channel/NewsChannelTest.kt rename to core/src/jvmTest/kotlin/entity/channel/NewsChannelTest.kt index 9ac4d6b80206..ee9d7b06b25b 100644 --- a/core/src/test/kotlin/entity/channel/NewsChannelTest.kt +++ b/core/src/jvmTest/kotlin/entity/channel/NewsChannelTest.kt @@ -3,11 +3,11 @@ package dev.kord.core.entity.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class NewsChannelTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() NewsChannel(ChannelData(id, guildId = guildId.optionalSnowflake(), type = ChannelType.GuildNews), kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/channel/TextChannelTest.kt b/core/src/jvmTest/kotlin/entity/channel/TextChannelTest.kt similarity index 84% rename from core/src/test/kotlin/entity/channel/TextChannelTest.kt rename to core/src/jvmTest/kotlin/entity/channel/TextChannelTest.kt index 3edf1c227a87..0ec14972d899 100644 --- a/core/src/test/kotlin/entity/channel/TextChannelTest.kt +++ b/core/src/jvmTest/kotlin/entity/channel/TextChannelTest.kt @@ -3,11 +3,11 @@ package dev.kord.core.entity.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class TextChannelTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() TextChannel(ChannelData(id, guildId = guildId.optionalSnowflake(), type = ChannelType.GuildNews), kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/entity/channel/VoiceChannelTest.kt b/core/src/jvmTest/kotlin/entity/channel/VoiceChannelTest.kt similarity index 84% rename from core/src/test/kotlin/entity/channel/VoiceChannelTest.kt rename to core/src/jvmTest/kotlin/entity/channel/VoiceChannelTest.kt index a6101b31c449..c2788de85d6a 100644 --- a/core/src/test/kotlin/entity/channel/VoiceChannelTest.kt +++ b/core/src/jvmTest/kotlin/entity/channel/VoiceChannelTest.kt @@ -3,11 +3,11 @@ package dev.kord.core.entity.channel import dev.kord.common.entity.ChannelType import dev.kord.common.entity.optional.optionalSnowflake import dev.kord.core.cache.data.ChannelData -import equality.GuildChannelEqualityTest -import mockKord +import dev.kord.core.equality.GuildChannelEqualityTest +import dev.kord.core.mockKord @Suppress("DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE") internal class VoiceChannelTest : GuildChannelEqualityTest by GuildChannelEqualityTest({ id, guildId -> val kord = mockKord() VoiceChannel(ChannelData(id, guildId = guildId.optionalSnowflake(), type = ChannelType.GuildNews), kord) -}) \ No newline at end of file +}) diff --git a/core/src/test/kotlin/equality/BehaviorEqualityTest.kt b/core/src/jvmTest/kotlin/equality/BehaviorEqualityTest.kt similarity index 90% rename from core/src/test/kotlin/equality/BehaviorEqualityTest.kt rename to core/src/jvmTest/kotlin/equality/BehaviorEqualityTest.kt index ea568cdbc415..0c9fdd641491 100644 --- a/core/src/test/kotlin/equality/BehaviorEqualityTest.kt +++ b/core/src/jvmTest/kotlin/equality/BehaviorEqualityTest.kt @@ -1,6 +1,7 @@ -package equality +package dev.kord.core.equality import dev.kord.core.entity.KordEntity +import dev.kord.core.randomId import kotlin.test.Test import kotlin.test.assertEquals @@ -24,4 +25,4 @@ interface BehaviorEqualityTest : EntityEqualityTest { assertEquals(behavior, entity) } -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/equality/ChannelEqualityTest.kt b/core/src/jvmTest/kotlin/equality/ChannelEqualityTest.kt similarity index 85% rename from core/src/test/kotlin/equality/ChannelEqualityTest.kt rename to core/src/jvmTest/kotlin/equality/ChannelEqualityTest.kt index abbc4aca40cd..f3c4e7138777 100644 --- a/core/src/test/kotlin/equality/ChannelEqualityTest.kt +++ b/core/src/jvmTest/kotlin/equality/ChannelEqualityTest.kt @@ -1,14 +1,16 @@ -package equality +package dev.kord.core.equality import dev.kord.common.entity.Snowflake import dev.kord.core.behavior.channel.ChannelBehavior import dev.kord.core.entity.KordEntity -import mockKord +import dev.kord.core.mockKord +import dev.kord.core.randomId +import kotlin.test.Test import kotlin.test.assertEquals interface ChannelEqualityTest : EntityEqualityTest { - @kotlin.test.Test + @Test fun `Channel is equal to Channel with the same id`() { val id = randomId() val kord = mockKord() @@ -24,4 +26,4 @@ interface ChannelEqualityTest : EntityEqualityTest { } } -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/equality/EntityEqualityTest.kt b/core/src/jvmTest/kotlin/equality/EntityEqualityTest.kt similarity index 74% rename from core/src/test/kotlin/equality/EntityEqualityTest.kt rename to core/src/jvmTest/kotlin/equality/EntityEqualityTest.kt index 64d8ab36faf3..40d752b55fc8 100644 --- a/core/src/test/kotlin/equality/EntityEqualityTest.kt +++ b/core/src/jvmTest/kotlin/equality/EntityEqualityTest.kt @@ -1,19 +1,12 @@ -package equality +package dev.kord.core.equality import dev.kord.common.entity.Snowflake import dev.kord.core.entity.KordEntity -import kotlin.random.Random -import kotlin.random.nextULong +import dev.kord.core.randomId import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals -val ids = generateSequence { - Random.nextULong(Snowflake.validValues) // limit to valid range to guarantee distinct generated Snowflakes -}.distinct().iterator() - -fun randomId() = Snowflake(ids.next()) - interface EntityEqualityTest { fun newEntity(id: Snowflake): T diff --git a/core/src/test/kotlin/equality/GuildChannelEqualityTest.kt b/core/src/jvmTest/kotlin/equality/GuildChannelEqualityTest.kt similarity index 93% rename from core/src/test/kotlin/equality/GuildChannelEqualityTest.kt rename to core/src/jvmTest/kotlin/equality/GuildChannelEqualityTest.kt index 39951040f031..ede33df820cf 100644 --- a/core/src/test/kotlin/equality/GuildChannelEqualityTest.kt +++ b/core/src/jvmTest/kotlin/equality/GuildChannelEqualityTest.kt @@ -1,4 +1,4 @@ -package equality +package dev.kord.core.equality import dev.kord.common.entity.Snowflake import dev.kord.core.entity.KordEntity @@ -13,4 +13,4 @@ interface GuildChannelEqualityTest : } } -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/equality/GuildEntityEqualityTest.kt b/core/src/jvmTest/kotlin/equality/GuildEntityEqualityTest.kt similarity index 94% rename from core/src/test/kotlin/equality/GuildEntityEqualityTest.kt rename to core/src/jvmTest/kotlin/equality/GuildEntityEqualityTest.kt index 702e662f044e..4a8dd284c7be 100644 --- a/core/src/test/kotlin/equality/GuildEntityEqualityTest.kt +++ b/core/src/jvmTest/kotlin/equality/GuildEntityEqualityTest.kt @@ -1,7 +1,8 @@ -package equality +package dev.kord.core.equality import dev.kord.common.entity.Snowflake import dev.kord.core.entity.KordEntity +import dev.kord.core.randomId import kotlin.test.Test import kotlin.test.assertNotEquals diff --git a/core/src/test/kotlin/interaction/CommandTypesTest.kt b/core/src/jvmTest/kotlin/interaction/CommandTypesTest.kt similarity index 86% rename from core/src/test/kotlin/interaction/CommandTypesTest.kt rename to core/src/jvmTest/kotlin/interaction/CommandTypesTest.kt index e69dd9af391f..aa97c32046ed 100644 --- a/core/src/test/kotlin/interaction/CommandTypesTest.kt +++ b/core/src/jvmTest/kotlin/interaction/CommandTypesTest.kt @@ -1,14 +1,17 @@ -package interaction +package dev.kord.core.interaction -import dev.kord.common.annotation.KordPreview import dev.kord.common.entity.ApplicationCommandOptionType import dev.kord.common.entity.InteractionCallbackData import dev.kord.core.cache.data.ApplicationInteractionData -import dev.kord.core.entity.interaction.* +import dev.kord.core.entity.interaction.GroupCommand +import dev.kord.core.entity.interaction.InteractionCommand +import dev.kord.core.entity.interaction.RootCommand +import dev.kord.core.entity.interaction.SubCommand +import dev.kord.core.mockKord import kotlinx.serialization.json.* -import mockKord import org.junit.jupiter.api.Test import kotlin.test.assertEquals +import kotlin.test.assertIs class CommandsTypeTests { @@ -52,8 +55,7 @@ class CommandsTypeTests { val serializedRoot = Json.decodeFromJsonElement(InteractionCallbackData.serializer(), root) val data = ApplicationInteractionData.from(serializedRoot, null) val command = InteractionCommand(data, mockKord()) - assert(command is RootCommand) - command as RootCommand + assertIs(command) assertEquals(1L, command.integers["argument"]) assertEquals("root", command.rootName) @@ -64,8 +66,7 @@ class CommandsTypeTests { val sub = Json.decodeFromJsonElement(InteractionCallbackData.serializer(), subCommand) val data = ApplicationInteractionData.from(sub, null) val command = InteractionCommand(data, mockKord()) - assert(command is SubCommand) - command as SubCommand + assertIs(command) assertEquals(1L, command.integers["argument"]) assertEquals("root", command.rootName) assertEquals("subCommand", command.name) @@ -77,11 +78,10 @@ class CommandsTypeTests { val grouping = Json.decodeFromJsonElement(InteractionCallbackData.serializer(), group) val data = ApplicationInteractionData.from(grouping, null) val command = InteractionCommand(data, mockKord()) - assert(command is GroupCommand) - command as GroupCommand + assertIs(command) assertEquals(1L, command.integers["argument"]) assertEquals("root", command.rootName) assertEquals("group", command.groupName) assertEquals("subCommand", command.name) } -} \ No newline at end of file +} diff --git a/core/src/test/kotlin/rest/RestTest.kt b/core/src/jvmTest/kotlin/rest/RestTest.kt similarity index 98% rename from core/src/test/kotlin/rest/RestTest.kt rename to core/src/jvmTest/kotlin/rest/RestTest.kt index 17de2bbd1dd7..a4b3c8a61403 100644 --- a/core/src/test/kotlin/rest/RestTest.kt +++ b/core/src/jvmTest/kotlin/rest/RestTest.kt @@ -1,4 +1,4 @@ -package rest +package dev.kord.core.rest import dev.kord.common.Color import dev.kord.common.entity.* @@ -172,7 +172,7 @@ class RestServiceTest { content = "TEST REPLY" } - assert(reply.referencedMessage?.id == referenceMessage.id) + assertEquals(referenceMessage.id, reply.referencedMessage?.id) } val messages = channel.messages.toList() @@ -371,10 +371,10 @@ class RestServiceTest { val category = guild.createCategory("my category") val textChannel = category.createTextChannel("test child text channel") - assert(textChannel.category == category) + assertEquals(category, textChannel.category) val voiceChannel = category.createVoiceChannel("test child voice channel") - assert(voiceChannel.category == category) + assertEquals(category, voiceChannel.category) } @Test diff --git a/core/src/test/resources/images/gitlab.png b/core/src/jvmTest/resources/images/gitlab.png similarity index 100% rename from core/src/test/resources/images/gitlab.png rename to core/src/jvmTest/resources/images/gitlab.png diff --git a/core/src/test/resources/images/kord.png b/core/src/jvmTest/resources/images/kord.png similarity index 100% rename from core/src/test/resources/images/kord.png rename to core/src/jvmTest/resources/images/kord.png diff --git a/core/src/test/resources/images/kord_icon.png b/core/src/jvmTest/resources/images/kord_icon.png similarity index 100% rename from core/src/test/resources/images/kord_icon.png rename to core/src/jvmTest/resources/images/kord_icon.png diff --git a/core/src/test/resources/interaction/groupsubcommand.json b/core/src/jvmTest/resources/interaction/groupsubcommand.json similarity index 100% rename from core/src/test/resources/interaction/groupsubcommand.json rename to core/src/jvmTest/resources/interaction/groupsubcommand.json diff --git a/core/src/test/resources/interaction/rootcommand.json b/core/src/jvmTest/resources/interaction/rootcommand.json similarity index 100% rename from core/src/test/resources/interaction/rootcommand.json rename to core/src/jvmTest/resources/interaction/rootcommand.json diff --git a/core/src/test/resources/interaction/subcommand.json b/core/src/jvmTest/resources/interaction/subcommand.json similarity index 100% rename from core/src/test/resources/interaction/subcommand.json rename to core/src/jvmTest/resources/interaction/subcommand.json diff --git a/core/src/test/resources/simplelogger.properties b/core/src/jvmTest/resources/simplelogger.properties similarity index 100% rename from core/src/test/resources/simplelogger.properties rename to core/src/jvmTest/resources/simplelogger.properties diff --git a/core/src/test/kotlin/KordTest.kt b/core/src/test/kotlin/KordTest.kt deleted file mode 100644 index a1f93cded382..000000000000 --- a/core/src/test/kotlin/KordTest.kt +++ /dev/null @@ -1,20 +0,0 @@ -import dev.kord.core.Kord -import dev.kord.core.event.gateway.ReadyEvent -import dev.kord.core.on -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Test -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable -import kotlin.test.assertEquals - -@EnabledIfEnvironmentVariable(named = "KORD_TEST_TOKEN", matches = ".+") -internal class KordTest { - - @Test - fun `Kord life cycle is correctly ended on shutdown`() = runBlocking { - val kord = Kord.restOnly(System.getenv("KORD_TEST_TOKEN")) - val job = kord.on {} - kord.shutdown() - assertEquals(false, job.isActive) - - } -} diff --git a/core/src/test/kotlin/StrategyTest.kt b/core/src/test/kotlin/StrategyTest.kt deleted file mode 100644 index 2175d45597ba..000000000000 --- a/core/src/test/kotlin/StrategyTest.kt +++ /dev/null @@ -1,54 +0,0 @@ -import dev.kord.cache.api.put -import dev.kord.core.Kord -import dev.kord.core.supplier.EntitySupplyStrategy -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.* -import org.junit.jupiter.api.condition.EnabledIfEnvironmentVariable -import kotlin.test.assertEquals -import kotlin.test.assertNotNull -import kotlin.test.assertNull - -@TestInstance(TestInstance.Lifecycle.PER_CLASS) -@EnabledIfEnvironmentVariable(named = "KORD_TEST_TOKEN", matches = ".+") -class StrategyTest { - - lateinit var kord: Kord - - @BeforeAll - fun setup() = runBlocking { - kord = Kord(System.getenv("KORD_TEST_TOKEN")) - } - - @Test - @Order(1) - fun `rest only`() = runBlocking { - val fromRest = kord.with(EntitySupplyStrategy.rest).getSelfOrNull() - val inCache = kord.with(EntitySupplyStrategy.cache).getSelfOrNull() - assertNull(inCache) - assertNotNull(fromRest) - } - - @Test - @Order(3) - fun `cache only`() = runBlocking { - - val inCache = kord.with(EntitySupplyStrategy.cache).getSelfOrNull() - assertNotNull(inCache) - } - - @Test - @Order(2) - fun `cache falls back to rest`() = runBlocking { - val cache = kord.with(EntitySupplyStrategy.cache) - val inCache = cache.getSelfOrNull() - - assertNull(inCache) - - val self = kord.getSelf() - assertNotNull(self) - kord.cache.put(self.data) - - assertEquals(self, cache.getSelf()) - - } -} \ No newline at end of file diff --git a/gateway/README.md b/gateway/README.md index cc713636fcc3..19ca819f8ea8 100644 --- a/gateway/README.md +++ b/gateway/README.md @@ -108,7 +108,7 @@ dependencies { dev.kord - kord-gateway + kord-gateway-jvm {version} ``` diff --git a/gateway/api/gateway.api b/gateway/api/gateway.api index a69e58ec7562..ce80685b8460 100644 --- a/gateway/api/gateway.api +++ b/gateway/api/gateway.api @@ -1918,6 +1918,10 @@ public final class dev/kord/gateway/UserUpdate : dev/kord/gateway/DispatchEvent public fun toString ()Ljava/lang/String; } +public final class dev/kord/gateway/UtilsKt { + public static final fun error (Lmu/KLogger;Ljava/lang/Throwable;)V +} + public final class dev/kord/gateway/VoiceServerUpdate : dev/kord/gateway/DispatchEvent { public fun (Ldev/kord/common/entity/DiscordVoiceServerUpdateData;Ljava/lang/Integer;)V public final fun component1 ()Ldev/kord/common/entity/DiscordVoiceServerUpdateData; diff --git a/gateway/build.gradle.kts b/gateway/build.gradle.kts index 8019d729397b..17f13890306b 100644 --- a/gateway/build.gradle.kts +++ b/gateway/build.gradle.kts @@ -1,18 +1,23 @@ plugins { - `kord-module` - `kord-sampled-module` + `kord-multiplatform-module` `kord-publishing` } -dependencies { - api(projects.common) +kotlin { + sourceSets { + commonMain { + dependencies { + api(projects.common) - api(libs.bundles.ktor.client.serialization) - api(libs.ktor.client.websockets) - api(libs.ktor.client.cio) - - ksp(projects.kspProcessors) - - testImplementation(libs.bundles.test.implementation) - testRuntimeOnly(libs.bundles.test.runtime) + api(libs.bundles.ktor.client.serialization) + api(libs.ktor.client.websockets) + } + } + jsMain { + dependencies { + implementation(libs.kotlinx.nodejs) + implementation(npm("fast-zlib", libs.versions.fastZlib.get())) + } + } + } } diff --git a/gateway/src/main/kotlin/Command.kt b/gateway/src/commonMain/kotlin/Command.kt similarity index 100% rename from gateway/src/main/kotlin/Command.kt rename to gateway/src/commonMain/kotlin/Command.kt diff --git a/gateway/src/main/kotlin/DefaultGateway.kt b/gateway/src/commonMain/kotlin/DefaultGateway.kt similarity index 94% rename from gateway/src/main/kotlin/DefaultGateway.kt rename to gateway/src/commonMain/kotlin/DefaultGateway.kt index 933e2a8ce6c4..42ad204cfb38 100644 --- a/gateway/src/main/kotlin/DefaultGateway.kt +++ b/gateway/src/commonMain/kotlin/DefaultGateway.kt @@ -11,7 +11,6 @@ import io.ktor.client.* import io.ktor.client.plugins.websocket.* import io.ktor.client.request.* import io.ktor.http.* -import io.ktor.util.logging.* import io.ktor.websocket.* import kotlinx.atomicfu.AtomicRef import kotlinx.atomicfu.atomic @@ -24,9 +23,6 @@ import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import kotlinx.serialization.json.Json import mu.KotlinLogging -import java.io.ByteArrayOutputStream -import java.util.zip.Inflater -import java.util.zip.InflaterOutputStream import kotlin.contracts.InvocationKind import kotlin.contracts.contract import kotlin.coroutines.CoroutineContext @@ -34,6 +30,8 @@ import kotlin.time.Duration private val defaultGatewayLogger = KotlinLogging.logger { } +internal expect fun Throwable.isTimeout(): Boolean + private sealed class State(val retry: Boolean) { object Stopped : State(false) class Running(retry: Boolean) : State(retry) @@ -122,7 +120,7 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { inflater = Inflater() } catch (exception: Exception) { defaultGatewayLogger.error(exception) - if (exception is java.nio.channels.UnresolvedAddressException) { + if (exception.isTimeout()) { data.eventFlow.emit(Close.Timeout) } @@ -179,21 +177,11 @@ public class DefaultGateway(private val data: DefaultGatewayData) : Gateway { } } - private fun Frame.deflateData(): String { - val outputStream = ByteArrayOutputStream() - InflaterOutputStream(outputStream, inflater).use { - it.write(data) - } - - return outputStream.use { - String(outputStream.toByteArray(), 0, outputStream.size(), Charsets.UTF_8) - } - } - private suspend fun read(frame: Frame) { + defaultGatewayLogger.trace { "Received raw frame: $frame" } val json = when { - compression -> frame.deflateData() - else -> String(frame.data, Charsets.UTF_8) + compression -> with(inflater) { frame.inflateData() } + else -> frame.data.decodeToString() } try { @@ -317,7 +305,7 @@ internal val GatewayConfiguration.identify ) -internal val os: String get() = System.getProperty("os.name") +internal expect val os: String internal val GatewayCloseCode.retry get() = when (this) { //this statement is intentionally structured to ensure we consider the retry for every new code diff --git a/gateway/src/main/kotlin/DefaultGatewayBuilder.kt b/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt similarity index 96% rename from gateway/src/main/kotlin/DefaultGatewayBuilder.kt rename to gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt index ee1f319ec880..080e2000761c 100644 --- a/gateway/src/main/kotlin/DefaultGatewayBuilder.kt +++ b/gateway/src/commonMain/kotlin/DefaultGatewayBuilder.kt @@ -1,13 +1,13 @@ package dev.kord.gateway import dev.kord.common.KordConfiguration +import dev.kord.common.http.HttpEngine import dev.kord.common.ratelimit.IntervalRateLimiter import dev.kord.common.ratelimit.RateLimiter import dev.kord.gateway.ratelimit.IdentifyRateLimiter import dev.kord.gateway.retry.LinearRetry import dev.kord.gateway.retry.Retry import io.ktor.client.* -import io.ktor.client.engine.cio.* import io.ktor.client.plugins.contentnegotiation.* import io.ktor.client.plugins.websocket.* import io.ktor.client.request.* @@ -29,7 +29,7 @@ public class DefaultGatewayBuilder { public var eventFlow: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = Int.MAX_VALUE) public fun build(): DefaultGateway { - val client = client ?: HttpClient(CIO) { + val client = client ?: HttpClient(HttpEngine) { install(WebSockets) install(ContentNegotiation) { json() diff --git a/gateway/src/main/kotlin/Event.kt b/gateway/src/commonMain/kotlin/Event.kt similarity index 100% rename from gateway/src/main/kotlin/Event.kt rename to gateway/src/commonMain/kotlin/Event.kt diff --git a/gateway/src/main/kotlin/Gateway.kt b/gateway/src/commonMain/kotlin/Gateway.kt similarity index 100% rename from gateway/src/main/kotlin/Gateway.kt rename to gateway/src/commonMain/kotlin/Gateway.kt diff --git a/gateway/src/main/kotlin/GatewayConfiguration.kt b/gateway/src/commonMain/kotlin/GatewayConfiguration.kt similarity index 100% rename from gateway/src/main/kotlin/GatewayConfiguration.kt rename to gateway/src/commonMain/kotlin/GatewayConfiguration.kt diff --git a/gateway/src/commonMain/kotlin/Inflater.kt b/gateway/src/commonMain/kotlin/Inflater.kt new file mode 100644 index 000000000000..30781d20a1fa --- /dev/null +++ b/gateway/src/commonMain/kotlin/Inflater.kt @@ -0,0 +1,7 @@ +package dev.kord.gateway + +import io.ktor.websocket.* + +internal expect class Inflater() { + fun Frame.inflateData(): String +} diff --git a/gateway/src/main/kotlin/Intent.kt b/gateway/src/commonMain/kotlin/Intent.kt similarity index 99% rename from gateway/src/main/kotlin/Intent.kt rename to gateway/src/commonMain/kotlin/Intent.kt index edc0b627cf1d..e54eff248fa0 100644 --- a/gateway/src/main/kotlin/Intent.kt +++ b/gateway/src/commonMain/kotlin/Intent.kt @@ -12,10 +12,11 @@ import kotlinx.serialization.descriptors.SerialDescriptor import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import kotlin.RequiresOptIn.Level.ERROR -import kotlin.annotation.AnnotationRetention.RUNTIME +import kotlin.annotation.AnnotationRetention.BINARY import kotlin.annotation.AnnotationTarget.* import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmName /** * Some [Intent]s are defined as "privileged" due to the sensitive nature of the data and cannot be used by Kord without @@ -36,7 +37,7 @@ import kotlin.contracts.contract "more info on how to enable these.", level = ERROR, ) -@Retention(RUNTIME) +@Retention(BINARY) @Target(CLASS, PROPERTY, FUNCTION) public annotation class PrivilegedIntent diff --git a/gateway/src/main/kotlin/OpCode.kt b/gateway/src/commonMain/kotlin/OpCode.kt similarity index 100% rename from gateway/src/main/kotlin/OpCode.kt rename to gateway/src/commonMain/kotlin/OpCode.kt diff --git a/gateway/src/main/kotlin/Sequence.kt b/gateway/src/commonMain/kotlin/Sequence.kt similarity index 100% rename from gateway/src/main/kotlin/Sequence.kt rename to gateway/src/commonMain/kotlin/Sequence.kt diff --git a/gateway/src/main/kotlin/Ticker.kt b/gateway/src/commonMain/kotlin/Ticker.kt similarity index 56% rename from gateway/src/main/kotlin/Ticker.kt rename to gateway/src/commonMain/kotlin/Ticker.kt index e1cb39eaf578..99c35b6a3a07 100644 --- a/gateway/src/main/kotlin/Ticker.kt +++ b/gateway/src/commonMain/kotlin/Ticker.kt @@ -1,10 +1,10 @@ package dev.kord.gateway -import io.ktor.util.logging.* import kotlinx.coroutines.* -import kotlinx.coroutines.channels.ReceiveChannel -import kotlinx.coroutines.channels.consumeEach -import kotlinx.coroutines.channels.ticker +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock import mu.KotlinLogging @@ -17,7 +17,6 @@ private val logger = KotlinLogging.logger { } * * @param dispatcher The dispatchers the events will be fired on. */ -@ObsoleteCoroutinesApi public class Ticker(private val dispatcher: CoroutineDispatcher = Dispatchers.Default) : CoroutineScope { @@ -25,29 +24,32 @@ public class Ticker(private val dispatcher: CoroutineDispatcher = Dispatchers.De private val mutex = Mutex() - private var ticker: ReceiveChannel? = null + private var listener: Job? = null public suspend fun tickAt(intervalMillis: Long, block: suspend () -> Unit) { - stop() mutex.withLock { - ticker = ticker(intervalMillis) - - launch { - ticker?.consumeEach { - try { - block() - } catch (exception: Exception) { - logger.error(exception) - } + listener?.cancel() + listener = tickingFlow(intervalMillis).onEach { + try { + block() + } catch (exception: Exception) { + logger.error(exception) } - } + }.launchIn(this) } } public suspend fun stop() { mutex.withLock { - ticker?.cancel() + listener?.cancel() } } } + +private fun tickingFlow(period: Long): Flow = flow { + while (true) { + delay(period) + emit(Unit) + } +} diff --git a/gateway/src/commonMain/kotlin/Utils.kt b/gateway/src/commonMain/kotlin/Utils.kt new file mode 100644 index 000000000000..fd897c41b80c --- /dev/null +++ b/gateway/src/commonMain/kotlin/Utils.kt @@ -0,0 +1,6 @@ +package dev.kord.gateway + +import mu.KLogger + +@PublishedApi +internal fun KLogger.error(throwable: Throwable): Unit = error(throwable) { "" } diff --git a/gateway/src/main/kotlin/builder/LoginBuilder.kt b/gateway/src/commonMain/kotlin/builder/LoginBuilder.kt similarity index 100% rename from gateway/src/main/kotlin/builder/LoginBuilder.kt rename to gateway/src/commonMain/kotlin/builder/LoginBuilder.kt diff --git a/gateway/src/main/kotlin/builder/PresenceBuilder.kt b/gateway/src/commonMain/kotlin/builder/PresenceBuilder.kt similarity index 96% rename from gateway/src/main/kotlin/builder/PresenceBuilder.kt rename to gateway/src/commonMain/kotlin/builder/PresenceBuilder.kt index fdf5b9011e6e..66204208460c 100644 --- a/gateway/src/main/kotlin/builder/PresenceBuilder.kt +++ b/gateway/src/commonMain/kotlin/builder/PresenceBuilder.kt @@ -36,7 +36,7 @@ public class PresenceBuilder { game = DiscordBotActivity(name, ActivityType.Competing) } - public fun toUpdateStatus(): UpdateStatus = UpdateStatus(since, game?.let(::listOf).orEmpty(), status, afk) + public fun toUpdateStatus(): UpdateStatus = UpdateStatus(since, listOfNotNull(game), status, afk) public fun toPresence(): DiscordPresence = DiscordPresence(status, afk, since, game) } diff --git a/gateway/src/main/kotlin/builder/RequestGuildMembersBuilder.kt b/gateway/src/commonMain/kotlin/builder/RequestGuildMembersBuilder.kt similarity index 100% rename from gateway/src/main/kotlin/builder/RequestGuildMembersBuilder.kt rename to gateway/src/commonMain/kotlin/builder/RequestGuildMembersBuilder.kt diff --git a/gateway/src/main/kotlin/handler/Handler.kt b/gateway/src/commonMain/kotlin/handler/Handler.kt similarity index 93% rename from gateway/src/main/kotlin/handler/Handler.kt rename to gateway/src/commonMain/kotlin/handler/Handler.kt index 786b7d9e3af4..70277bfd3c91 100644 --- a/gateway/src/main/kotlin/handler/Handler.kt +++ b/gateway/src/commonMain/kotlin/handler/Handler.kt @@ -14,7 +14,7 @@ private val logger = KotlinLogging.logger("[Handler]") internal abstract class Handler( val flow: Flow, val name: String, - private val dispatcher: CoroutineDispatcher = Dispatchers.Default + dispatcher: CoroutineDispatcher = Dispatchers.Default ) : CoroutineScope { override val coroutineContext: CoroutineContext = SupervisorJob() + dispatcher @@ -36,4 +36,4 @@ internal abstract class Handler( }.launchIn(this) } -} \ No newline at end of file +} diff --git a/gateway/src/main/kotlin/handler/HandshakeHandler.kt b/gateway/src/commonMain/kotlin/handler/HandshakeHandler.kt similarity index 100% rename from gateway/src/main/kotlin/handler/HandshakeHandler.kt rename to gateway/src/commonMain/kotlin/handler/HandshakeHandler.kt diff --git a/gateway/src/main/kotlin/handler/HeartbeatHandler.kt b/gateway/src/commonMain/kotlin/handler/HeartbeatHandler.kt similarity index 95% rename from gateway/src/main/kotlin/handler/HeartbeatHandler.kt rename to gateway/src/commonMain/kotlin/handler/HeartbeatHandler.kt index 6e85bcdef94a..e363e982e3db 100644 --- a/gateway/src/main/kotlin/handler/HeartbeatHandler.kt +++ b/gateway/src/commonMain/kotlin/handler/HeartbeatHandler.kt @@ -3,13 +3,11 @@ package dev.kord.gateway.handler import dev.kord.gateway.* import kotlinx.atomicfu.atomic import kotlinx.atomicfu.update -import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlin.time.Duration import kotlin.time.TimeMark import kotlin.time.TimeSource -@OptIn(ObsoleteCoroutinesApi::class) internal class HeartbeatHandler( flow: Flow, private val send: suspend (Command) -> Unit, @@ -67,4 +65,4 @@ internal class HeartbeatHandler( private fun setPossibleZombie() { possibleZombie.update { true } } -} \ No newline at end of file +} diff --git a/gateway/src/main/kotlin/handler/InvalidSessionHandler.kt b/gateway/src/commonMain/kotlin/handler/InvalidSessionHandler.kt similarity index 100% rename from gateway/src/main/kotlin/handler/InvalidSessionHandler.kt rename to gateway/src/commonMain/kotlin/handler/InvalidSessionHandler.kt diff --git a/gateway/src/main/kotlin/handler/ReconnectHandler.kt b/gateway/src/commonMain/kotlin/handler/ReconnectHandler.kt similarity index 87% rename from gateway/src/main/kotlin/handler/ReconnectHandler.kt rename to gateway/src/commonMain/kotlin/handler/ReconnectHandler.kt index 390d0a813513..c25bed3a484b 100644 --- a/gateway/src/main/kotlin/handler/ReconnectHandler.kt +++ b/gateway/src/commonMain/kotlin/handler/ReconnectHandler.kt @@ -2,7 +2,6 @@ package dev.kord.gateway.handler import dev.kord.gateway.Event import dev.kord.gateway.Reconnect -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow internal class ReconnectHandler( @@ -15,4 +14,4 @@ internal class ReconnectHandler( reconnect() } } -} \ No newline at end of file +} diff --git a/gateway/src/main/kotlin/handler/SequenceHandler.kt b/gateway/src/commonMain/kotlin/handler/SequenceHandler.kt similarity index 100% rename from gateway/src/main/kotlin/handler/SequenceHandler.kt rename to gateway/src/commonMain/kotlin/handler/SequenceHandler.kt diff --git a/gateway/src/main/kotlin/ratelimit/IdentifyRateLimiter.kt b/gateway/src/commonMain/kotlin/ratelimit/IdentifyRateLimiter.kt similarity index 98% rename from gateway/src/main/kotlin/ratelimit/IdentifyRateLimiter.kt rename to gateway/src/commonMain/kotlin/ratelimit/IdentifyRateLimiter.kt index 9df2b725db93..17e2662f4325 100644 --- a/gateway/src/main/kotlin/ratelimit/IdentifyRateLimiter.kt +++ b/gateway/src/commonMain/kotlin/ratelimit/IdentifyRateLimiter.kt @@ -11,6 +11,7 @@ import kotlinx.coroutines.channels.onSuccess import kotlinx.coroutines.flow.* import kotlinx.coroutines.selects.select import mu.KotlinLogging +import kotlin.jvm.JvmField import kotlin.time.Duration.Companion.seconds import kotlin.time.times @@ -248,10 +249,9 @@ private class IdentifyRateLimiterImpl( private val ExceptionLogger = CoroutineExceptionHandler { context, exception -> // we can't be cancelled (GlobalScope) and we never close the channel, so all exceptions are bugs - logger.error( - "IdentifyRateLimiter threw an exception in context $context, please report this, it should not happen", - exception, - ) + logger.error(exception) { + "IdentifyRateLimiter threw an exception in context $context, please report this, it should not happen" + } } } } diff --git a/gateway/src/main/kotlin/retry/LinearRetry.kt b/gateway/src/commonMain/kotlin/retry/LinearRetry.kt similarity index 100% rename from gateway/src/main/kotlin/retry/LinearRetry.kt rename to gateway/src/commonMain/kotlin/retry/LinearRetry.kt diff --git a/gateway/src/main/kotlin/retry/Retry.kt b/gateway/src/commonMain/kotlin/retry/Retry.kt similarity index 100% rename from gateway/src/main/kotlin/retry/Retry.kt rename to gateway/src/commonMain/kotlin/retry/Retry.kt diff --git a/gateway/src/test/kotlin/gateway/DefaultGatewayTest.kt b/gateway/src/commonTest/kotlin/DefaultGatewayTest.kt similarity index 52% rename from gateway/src/test/kotlin/gateway/DefaultGatewayTest.kt rename to gateway/src/commonTest/kotlin/DefaultGatewayTest.kt index c9873fe62eab..830f2994635f 100644 --- a/gateway/src/test/kotlin/gateway/DefaultGatewayTest.kt +++ b/gateway/src/commonTest/kotlin/DefaultGatewayTest.kt @@ -1,4 +1,4 @@ -package gateway +package dev.kord.gateway import dev.kord.common.entity.ActivityType import dev.kord.common.entity.DiscordBotActivity @@ -6,8 +6,8 @@ import dev.kord.common.entity.PresenceStatus import dev.kord.common.ratelimit.IntervalRateLimiter import dev.kord.gateway.* import dev.kord.gateway.retry.LinearRetry +import dev.kord.test.getEnv import io.ktor.client.* -import io.ktor.client.engine.cio.* import io.ktor.client.plugins.contentnegotiation.* import io.ktor.client.plugins.websocket.* import io.ktor.serialization.kotlinx.json.* @@ -18,26 +18,21 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Disabled -import org.junit.jupiter.api.Test +import kotlinx.coroutines.test.runTest +import kotlin.js.JsName +import kotlin.test.Ignore +import kotlin.test.Test import kotlin.time.Duration.Companion.seconds class DefaultGatewayTest { @OptIn(DelicateCoroutinesApi::class) @Test - @Disabled - fun `default gateway functions correctly`() { - val token = System.getenv("KORD_TEST_TOKEN") + @JsName("test1") + @Ignore + fun `default gateway functions correctly`() = runTest { + val token = getEnv("KORD_TEST_TOKEN") ?: error("Missing env variable KORD_TEST_TOKEN") val gateway = DefaultGateway { - client = HttpClient(CIO) { - install(WebSockets) - install(ContentNegotiation) { - json() - } - } - reconnectRetry = LinearRetry(2.seconds, 20.seconds, 10) sendRateLimiter = IntervalRateLimiter(limit = 120, interval = 60.seconds) } @@ -49,17 +44,35 @@ class DefaultGatewayTest { "!restart" -> gateway.restart(Close.Reconnecting) "!detach" -> gateway.detach() "!status" -> when (words.getOrNull(1)) { - "playing" -> gateway.send(UpdateStatus(status = PresenceStatus.Online, afk = false, activities = listOf(DiscordBotActivity("Kord", ActivityType.Game)), since = null)) + "playing" -> gateway.send( + UpdateStatus( + status = PresenceStatus.Online, + afk = false, + activities = listOf(DiscordBotActivity("Kord", ActivityType.Game)), + since = null + ) + ) } - "!ping" -> gateway.send(UpdateStatus(status = PresenceStatus.Online, afk = false, activities = listOf(DiscordBotActivity("Ping is ${gateway.ping.value?.inWholeMilliseconds}", ActivityType.Game)), since = null)) + + "!ping" -> gateway.send( + UpdateStatus( + status = PresenceStatus.Online, + afk = false, + activities = listOf( + DiscordBotActivity( + "Ping is ${gateway.ping.value?.inWholeMilliseconds}", + ActivityType.Game + ) + ), + since = null + ) + ) } }.launchIn(GlobalScope) - runBlocking { - gateway.start(token) { - @OptIn(PrivilegedIntent::class) - intents = Intents.all - } + gateway.start(token) { + @OptIn(PrivilegedIntent::class) + intents = Intents.all } } } diff --git a/gateway/src/test/kotlin/json/CommandTest.kt b/gateway/src/commonTest/kotlin/json/CommandTest.kt similarity index 94% rename from gateway/src/test/kotlin/json/CommandTest.kt rename to gateway/src/commonTest/kotlin/json/CommandTest.kt index 4c8d834c7711..5e7420f4c1db 100644 --- a/gateway/src/test/kotlin/json/CommandTest.kt +++ b/gateway/src/commonTest/kotlin/json/CommandTest.kt @@ -1,4 +1,4 @@ -package json +package dev.kord.gateway.json import dev.kord.common.entity.DiscordBotActivity import dev.kord.common.entity.DiscordShard @@ -11,14 +11,15 @@ import dev.kord.common.entity.optional.optionalInt import dev.kord.gateway.* import kotlinx.datetime.Instant import kotlinx.serialization.json.* -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import java.util.* +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals private val json = Json { encodeDefaults = false } class CommandTest { @Test + @JsName("test1") fun `Resume command serialization`() { val token = "token" val sessionId = "session" @@ -40,6 +41,7 @@ class CommandTest { @Test + @JsName("test2") fun `Heartbeat command serialization`() { val interval = 1337 @@ -55,6 +57,7 @@ class CommandTest { @Test + @JsName("test3") @OptIn(PrivilegedIntent::class) fun `RequestGuildMembers command serialization`() { val guildId = "1337" @@ -80,6 +83,7 @@ class CommandTest { @Test + @JsName("test4") fun `UpdateVoiceState command serialization`() { val guildId = "1337" val channelId = "420" @@ -106,6 +110,7 @@ class CommandTest { @Test + @JsName("test5") fun `UpdateState command serialization`() { val since = 1242518400L val activities = listOf() @@ -122,7 +127,7 @@ class CommandTest { put("d", buildJsonObject { put("since", since) put("activities", JsonArray(emptyList())) - put("status", status.value.lowercase(Locale.getDefault())) + put("status", status.value.lowercase()) put("afk", afk) }) }) @@ -133,6 +138,7 @@ class CommandTest { @OptIn(PrivilegedIntent::class) @Test + @JsName("test6") fun `Identify command serialization`() { val token = "test" val properties = IdentifyProperties("os", "browser", "device") diff --git a/gateway/src/test/kotlin/json/RegressionTests.kt b/gateway/src/commonTest/kotlin/json/RegressionTests.kt similarity index 57% rename from gateway/src/test/kotlin/json/RegressionTests.kt rename to gateway/src/commonTest/kotlin/json/RegressionTests.kt index 8b148930f63d..831aade5e824 100644 --- a/gateway/src/test/kotlin/json/RegressionTests.kt +++ b/gateway/src/commonTest/kotlin/json/RegressionTests.kt @@ -1,34 +1,37 @@ -package json +package dev.kord.gateway.json import dev.kord.gateway.Event import dev.kord.gateway.Reconnect +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test -private fun file(name: String): String { - val loader = SerializationTest::class.java.classLoader - return loader.getResource("json/regression/$name.json").readText() -} +private suspend fun file(name: String): String = readFile("regression", name) class RegressionTests { @Test - fun `Resume command serialization`() { + @JsName("test1") + fun `Resume command serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("eventWithDataThatShouldNotHaveData")) event shouldBe Reconnect } @Test - fun `Resumed with unknown data`() { + @JsName("test2") + fun `Resumed with unknown data`() = runTest { Json.decodeFromString(Event.DeserializationStrategy, file("resumeWithUnknownData")) } @Test - fun `PresenceReplace with unknown data`() { + @JsName("test3") + fun `PresenceReplace with unknown data`() = runTest { Json.decodeFromString(Event.DeserializationStrategy, file("presenceReplaceWithUnknownData")) } @Test - fun `Unknown event with successfully parses`() { + @JsName("test4") + fun `Unknown event with successfully parses`() = runTest { Json.decodeFromString(Event.DeserializationStrategy, file("eventWithUnknownData")) //dispatch event with non-existent type } diff --git a/gateway/src/test/kotlin/json/SerializationTest.kt b/gateway/src/commonTest/kotlin/json/SerializationTest.kt similarity index 83% rename from gateway/src/test/kotlin/json/SerializationTest.kt rename to gateway/src/commonTest/kotlin/json/SerializationTest.kt index b66a662b9424..8bdad14c8d2e 100644 --- a/gateway/src/test/kotlin/json/SerializationTest.kt +++ b/gateway/src/commonTest/kotlin/json/SerializationTest.kt @@ -1,30 +1,31 @@ -package json +package dev.kord.gateway.json import dev.kord.common.entity.UserFlags import dev.kord.common.entity.UserPremium import dev.kord.common.entity.optional.value import dev.kord.gateway.* +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Instant import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test import kotlin.time.Duration.Companion.seconds -private fun file(name: String): String { - val loader = SerializationTest::class.java.classLoader - return loader.getResource("json/event/$name.json")!!.readText() -} +private suspend fun file(name: String): String = readFile("event", name) class SerializationTest { @Test - fun `HeartbeatACK Event serialization`() { + @JsName("test1") + fun `HeartbeatACK Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("ack")) event shouldBe HeartbeatACK } @Test - fun `Hello Event serialization`() { + @JsName("test2") + fun `Hello Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("hello")) as Hello with(event) { heartbeatInterval shouldBe 1337 @@ -33,14 +34,16 @@ class SerializationTest { @Test - fun `Reconnect Event serialization`() { + @JsName("test3") + fun `Reconnect Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("reconnect")) event shouldBe Reconnect } @Test - fun `Ready Event serialization`() { + @JsName("test4") + fun `Ready Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("ready")) as Ready with(event.data) { with(event.data.guilds) { @@ -71,20 +74,23 @@ class SerializationTest { } @Test - fun `Resumed Event serialization`() { + @JsName("test5") + fun `Resumed Event serialization`() = runTest { Json.decodeFromString(Event.DeserializationStrategy, file("resumed")) as Resumed } @Test - fun `InvalidSession command serialization`() { + @JsName("test6") + fun `InvalidSession command serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("invalid")) as InvalidSession with(event) { resumable shouldBe false } } @Test - fun `ChannelPinsUpdate Event serialization`() { + @JsName("test7") + fun `ChannelPinsUpdate Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("channelpinsupdate")) as ChannelPinsUpdate with(event.pins) { guildId.value?.toString() shouldBe "41771983423143937" @@ -96,7 +102,8 @@ class SerializationTest { @Test - fun `ChannelCreate Event serialization`() { + @JsName("test8") + fun `ChannelCreate Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("channelcreate")) as ChannelCreate with(event.channel) { id.toString() shouldBe "41771983423143937" @@ -115,7 +122,8 @@ class SerializationTest { @Test - fun `ChannelUpdate Event serialization`() { + @JsName("test9") + fun `ChannelUpdate Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("channelupdate")) as ChannelUpdate with(event.channel) { id.toString() shouldBe "41771983423143937" @@ -133,7 +141,8 @@ class SerializationTest { } @Test - fun `ChannelDelete Event serialization`() { + @JsName("test10") + fun `ChannelDelete Event serialization`() = runTest { val event = Json.decodeFromString(Event.DeserializationStrategy, file("channeldelete")) as ChannelDelete with(event.channel) { id.toString() shouldBe "41771983423143937" diff --git a/gateway/src/test/kotlin/json/SnowflakeTest.kt b/gateway/src/commonTest/kotlin/json/SnowflakeTest.kt similarity index 93% rename from gateway/src/test/kotlin/json/SnowflakeTest.kt rename to gateway/src/commonTest/kotlin/json/SnowflakeTest.kt index bec8fd376ff9..b760627953ce 100644 --- a/gateway/src/test/kotlin/json/SnowflakeTest.kt +++ b/gateway/src/commonTest/kotlin/json/SnowflakeTest.kt @@ -1,4 +1,4 @@ -package json +package dev.kord.gateway.json import dev.kord.common.entity.Snowflake import kotlinx.serialization.Serializable @@ -8,6 +8,7 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.decodeFromJsonElement import kotlinx.serialization.json.put +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals @@ -17,6 +18,7 @@ class SnowflakeTest { private data class SnowflakeContainer(val snowflake: Snowflake) @Test + @JsName("test1") fun `Deserialization of Snowflake as String completes successfully`() { val value = "1337" val json = buildJsonObject { @@ -28,6 +30,7 @@ class SnowflakeTest { } @Test + @JsName("test2") fun `Deserialization of Snowflake as large String completes successfully`() { val value = Snowflake.validValues.last.toString() val json = buildJsonObject { @@ -39,6 +42,7 @@ class SnowflakeTest { } @Test + @JsName("test3") fun `Deserialization of Snowflake as Number completes successfully`() { val value = 1337L val json = buildJsonObject { @@ -50,6 +54,7 @@ class SnowflakeTest { } @Test + @JsName("test4") fun `Deserialization of Snowflake as large Number completes successfully`() { // ULong is inline class and therefore cannot extend abstract class Number but put only takes Number val value = Snowflake.validValues.last.toNumber() @@ -62,6 +67,7 @@ class SnowflakeTest { } @Test + @JsName("test5") fun `Reserialization of Snowflake completes successfully`() { val json = buildJsonObject { put("snowflake", 1337L) } diff --git a/gateway/src/test/kotlin/json/Util.kt b/gateway/src/commonTest/kotlin/json/Util.kt similarity index 83% rename from gateway/src/test/kotlin/json/Util.kt rename to gateway/src/commonTest/kotlin/json/Util.kt index dbdc90e3c5f9..0d653a4a4917 100644 --- a/gateway/src/test/kotlin/json/Util.kt +++ b/gateway/src/commonTest/kotlin/json/Util.kt @@ -1,7 +1,10 @@ -package json +package dev.kord.gateway.json +import dev.kord.test.file import kotlin.test.assertEquals +suspend fun readFile(prefix: String, name: String) = file("gateway", "json/$prefix/$name.json") + infix fun T.shouldBe(that: T) { assertEquals(that, this) } diff --git a/gateway/src/test/kotlin/ratelimit/IdentifyRateLimiterTest.kt b/gateway/src/commonTest/kotlin/ratelimit/IdentifyRateLimiterTest.kt similarity index 92% rename from gateway/src/test/kotlin/ratelimit/IdentifyRateLimiterTest.kt rename to gateway/src/commonTest/kotlin/ratelimit/IdentifyRateLimiterTest.kt index 1a591e6878ab..81d51da4ae0a 100644 --- a/gateway/src/test/kotlin/ratelimit/IdentifyRateLimiterTest.kt +++ b/gateway/src/commonTest/kotlin/ratelimit/IdentifyRateLimiterTest.kt @@ -1,4 +1,4 @@ -package ratelimit +package dev.kord.gateway.ratelimit import dev.kord.common.KordConfiguration import dev.kord.common.entity.DiscordUser @@ -8,19 +8,19 @@ import dev.kord.gateway.GatewayCloseCode.Unknown import dev.kord.gateway.InvalidSession import dev.kord.gateway.Ready import dev.kord.gateway.ReadyData -import dev.kord.gateway.ratelimit.IdentifyRateLimiter import kotlinx.coroutines.* import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.* import kotlinx.coroutines.flow.SharingStarted.Companion.Eagerly import kotlinx.coroutines.test.currentTime import kotlinx.coroutines.test.runTest -import org.junit.jupiter.api.assertThrows import kotlin.coroutines.ContinuationInterceptor +import kotlin.js.JsName import kotlin.random.Random import kotlin.random.nextInt import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.test.assertFailsWith import kotlin.test.assertTrue import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -53,10 +53,11 @@ private val CLOSE = DiscordClose(closeCode = Unknown, recoverable = true) class IdentifyRateLimiterTest { @Test - fun `IdentifyRateLimiter throws IAEs`() = runBlocking { - assertThrows { IdentifyRateLimiter(maxConcurrency = 0) } - assertThrows { IdentifyRateLimiter(maxConcurrency = -1) } - assertThrows { + @JsName("test1") + fun `IdentifyRateLimiter throws IAEs`() = runTest { + assertFailsWith { IdentifyRateLimiter(maxConcurrency = 0) } + assertFailsWith { IdentifyRateLimiter(maxConcurrency = -1) } + assertFailsWith { val rateLimiter = IdentifyRateLimiter(maxConcurrency = 1) rateLimiter.consume(shardId = -1, events = MutableSharedFlow()) } @@ -136,26 +137,32 @@ class IdentifyRateLimiterTest { // probably the most common case @Test + @JsName("test2") fun `single shard`() = testRateLimiter(shardIds = listOf(0), maxConcurrency = 1, expectedBuckets = 1) // https://discord.com/developers/docs/topics/gateway#sharding-max-concurrency @Test + @JsName("test3") fun `example 1`() = testRateLimiter(shardIds = 0..15, maxConcurrency = 16, expectedBuckets = 1) // https://discord.com/developers/docs/topics/gateway#sharding-max-concurrency @Test + @JsName("test4") fun `example 2`() = testRateLimiter(shardIds = 0..31, maxConcurrency = 16, expectedBuckets = 2) // https://discord.com/channels/613425648685547541/697489244649816084/1021565107949551676 @Test + @JsName("test5") fun `example 2 but without shards 15-30`() = testRateLimiter(shardIds = (0..14) + 31, maxConcurrency = 16, expectedBuckets = 1) // https://discord.com/channels/556525343595298817/1021384687337353216 @Test + @JsName("test6") fun `Schlaubi's case`() = testRateLimiter(shardIds = 0..14, maxConcurrency = 1, expectedBuckets = 15) @Test + @JsName("test7") fun `randomly distributed shards`() = testRateLimiter( shardIds = listOf(0, 4, 5, 10, 23), maxConcurrency = 2, @@ -164,6 +171,7 @@ class IdentifyRateLimiterTest { @Test + @JsName("test8") fun `IdentifyRateLimiter timeouts unresponsive gateways`() = runTest { val rateLimiter = IdentifyRateLimiter( maxConcurrency = 1, diff --git a/gateway/src/test/kotlin/helper/LinearRetryTest.kt b/gateway/src/commonTest/kotlin/retry/LinearRetryTest.kt similarity index 84% rename from gateway/src/test/kotlin/helper/LinearRetryTest.kt rename to gateway/src/commonTest/kotlin/retry/LinearRetryTest.kt index 5143c86af7b4..a11a53d9f8b4 100644 --- a/gateway/src/test/kotlin/helper/LinearRetryTest.kt +++ b/gateway/src/commonTest/kotlin/retry/LinearRetryTest.kt @@ -1,9 +1,9 @@ -package helper +package dev.kord.gateway.retry -import dev.kord.gateway.retry.LinearRetry import kotlinx.coroutines.test.currentTime import kotlinx.coroutines.test.runTest import kotlin.test.Test +import kotlin.test.assertEquals import kotlin.time.Duration.Companion.milliseconds import kotlin.time.Duration.Companion.seconds @@ -23,8 +23,8 @@ class LinearRetryTest { val end = currentTime val elapsed = (end - start).milliseconds - assert(elapsed == 55.seconds) - assert(i == 10) + assertEquals(55.seconds, elapsed) + assertEquals(10, i) } @Test @@ -41,6 +41,6 @@ class LinearRetryTest { val end = currentTime val elapsed = (end - start).milliseconds - assert(elapsed == 1000.seconds) + assertEquals(1000.seconds, elapsed) } } diff --git a/gateway/src/test/resources/json/event/ack.json b/gateway/src/commonTest/resources/json/event/ack.json similarity index 100% rename from gateway/src/test/resources/json/event/ack.json rename to gateway/src/commonTest/resources/json/event/ack.json diff --git a/gateway/src/test/resources/json/event/channelcreate.json b/gateway/src/commonTest/resources/json/event/channelcreate.json similarity index 100% rename from gateway/src/test/resources/json/event/channelcreate.json rename to gateway/src/commonTest/resources/json/event/channelcreate.json diff --git a/gateway/src/test/resources/json/event/channeldelete.json b/gateway/src/commonTest/resources/json/event/channeldelete.json similarity index 100% rename from gateway/src/test/resources/json/event/channeldelete.json rename to gateway/src/commonTest/resources/json/event/channeldelete.json diff --git a/gateway/src/test/resources/json/event/channelpinsupdate.json b/gateway/src/commonTest/resources/json/event/channelpinsupdate.json similarity index 100% rename from gateway/src/test/resources/json/event/channelpinsupdate.json rename to gateway/src/commonTest/resources/json/event/channelpinsupdate.json diff --git a/gateway/src/test/resources/json/event/channelupdate.json b/gateway/src/commonTest/resources/json/event/channelupdate.json similarity index 100% rename from gateway/src/test/resources/json/event/channelupdate.json rename to gateway/src/commonTest/resources/json/event/channelupdate.json diff --git a/gateway/src/test/resources/json/event/guildbanadd.json b/gateway/src/commonTest/resources/json/event/guildbanadd.json similarity index 100% rename from gateway/src/test/resources/json/event/guildbanadd.json rename to gateway/src/commonTest/resources/json/event/guildbanadd.json diff --git a/gateway/src/test/resources/json/event/guildbanremove.json b/gateway/src/commonTest/resources/json/event/guildbanremove.json similarity index 100% rename from gateway/src/test/resources/json/event/guildbanremove.json rename to gateway/src/commonTest/resources/json/event/guildbanremove.json diff --git a/gateway/src/test/resources/json/event/guildcreate.json b/gateway/src/commonTest/resources/json/event/guildcreate.json similarity index 100% rename from gateway/src/test/resources/json/event/guildcreate.json rename to gateway/src/commonTest/resources/json/event/guildcreate.json diff --git a/gateway/src/test/resources/json/event/guilddelete.json b/gateway/src/commonTest/resources/json/event/guilddelete.json similarity index 100% rename from gateway/src/test/resources/json/event/guilddelete.json rename to gateway/src/commonTest/resources/json/event/guilddelete.json diff --git a/gateway/src/test/resources/json/event/guildemojiupdate.json b/gateway/src/commonTest/resources/json/event/guildemojiupdate.json similarity index 100% rename from gateway/src/test/resources/json/event/guildemojiupdate.json rename to gateway/src/commonTest/resources/json/event/guildemojiupdate.json diff --git a/gateway/src/test/resources/json/event/guildintegrationsupdate.json b/gateway/src/commonTest/resources/json/event/guildintegrationsupdate.json similarity index 100% rename from gateway/src/test/resources/json/event/guildintegrationsupdate.json rename to gateway/src/commonTest/resources/json/event/guildintegrationsupdate.json diff --git a/gateway/src/test/resources/json/event/guildmemberadd.json b/gateway/src/commonTest/resources/json/event/guildmemberadd.json similarity index 100% rename from gateway/src/test/resources/json/event/guildmemberadd.json rename to gateway/src/commonTest/resources/json/event/guildmemberadd.json diff --git a/gateway/src/test/resources/json/event/guildmemeberremove.json b/gateway/src/commonTest/resources/json/event/guildmemeberremove.json similarity index 100% rename from gateway/src/test/resources/json/event/guildmemeberremove.json rename to gateway/src/commonTest/resources/json/event/guildmemeberremove.json diff --git a/gateway/src/test/resources/json/event/guildupdate.json b/gateway/src/commonTest/resources/json/event/guildupdate.json similarity index 100% rename from gateway/src/test/resources/json/event/guildupdate.json rename to gateway/src/commonTest/resources/json/event/guildupdate.json diff --git a/gateway/src/test/resources/json/event/hello.json b/gateway/src/commonTest/resources/json/event/hello.json similarity index 100% rename from gateway/src/test/resources/json/event/hello.json rename to gateway/src/commonTest/resources/json/event/hello.json diff --git a/gateway/src/test/resources/json/event/invalid.json b/gateway/src/commonTest/resources/json/event/invalid.json similarity index 100% rename from gateway/src/test/resources/json/event/invalid.json rename to gateway/src/commonTest/resources/json/event/invalid.json diff --git a/gateway/src/test/resources/json/event/ready.json b/gateway/src/commonTest/resources/json/event/ready.json similarity index 100% rename from gateway/src/test/resources/json/event/ready.json rename to gateway/src/commonTest/resources/json/event/ready.json diff --git a/gateway/src/test/resources/json/event/reconnect.json b/gateway/src/commonTest/resources/json/event/reconnect.json similarity index 100% rename from gateway/src/test/resources/json/event/reconnect.json rename to gateway/src/commonTest/resources/json/event/reconnect.json diff --git a/gateway/src/test/resources/json/event/resumed.json b/gateway/src/commonTest/resources/json/event/resumed.json similarity index 100% rename from gateway/src/test/resources/json/event/resumed.json rename to gateway/src/commonTest/resources/json/event/resumed.json diff --git a/gateway/src/test/resources/json/regression/eventWithDataThatShouldNotHaveData.json b/gateway/src/commonTest/resources/json/regression/eventWithDataThatShouldNotHaveData.json similarity index 100% rename from gateway/src/test/resources/json/regression/eventWithDataThatShouldNotHaveData.json rename to gateway/src/commonTest/resources/json/regression/eventWithDataThatShouldNotHaveData.json diff --git a/gateway/src/test/resources/json/regression/eventWithUnknownData.json b/gateway/src/commonTest/resources/json/regression/eventWithUnknownData.json similarity index 100% rename from gateway/src/test/resources/json/regression/eventWithUnknownData.json rename to gateway/src/commonTest/resources/json/regression/eventWithUnknownData.json diff --git a/gateway/src/test/resources/json/regression/presenceReplaceWithUnknownData.json b/gateway/src/commonTest/resources/json/regression/presenceReplaceWithUnknownData.json similarity index 100% rename from gateway/src/test/resources/json/regression/presenceReplaceWithUnknownData.json rename to gateway/src/commonTest/resources/json/regression/presenceReplaceWithUnknownData.json diff --git a/gateway/src/test/resources/json/regression/resumeWithUnknownData.json b/gateway/src/commonTest/resources/json/regression/resumeWithUnknownData.json similarity index 100% rename from gateway/src/test/resources/json/regression/resumeWithUnknownData.json rename to gateway/src/commonTest/resources/json/regression/resumeWithUnknownData.json diff --git a/gateway/src/test/resources/simplelogger.properties b/gateway/src/commonTest/resources/simplelogger.properties similarity index 100% rename from gateway/src/test/resources/simplelogger.properties rename to gateway/src/commonTest/resources/simplelogger.properties diff --git a/gateway/src/jsMain/kotlin/DefaultGateway.kt b/gateway/src/jsMain/kotlin/DefaultGateway.kt new file mode 100644 index 000000000000..c4d0d9eacf87 --- /dev/null +++ b/gateway/src/jsMain/kotlin/DefaultGateway.kt @@ -0,0 +1,7 @@ +package dev.kord.gateway + +import io.ktor.client.plugins.websocket.* +import node.process.process + +internal actual fun Throwable.isTimeout() = this is WebSocketException && "ENOTFOUND" in toString() +internal actual val os: String get() = process.platform.toString() diff --git a/gateway/src/jsMain/kotlin/Inflater.kt b/gateway/src/jsMain/kotlin/Inflater.kt new file mode 100644 index 000000000000..4d23682f8da2 --- /dev/null +++ b/gateway/src/jsMain/kotlin/Inflater.kt @@ -0,0 +1,16 @@ +package dev.kord.gateway + +import dev.kord.gateway.internal.Inflate +import io.ktor.websocket.* +import node.buffer.Buffer +import node.buffer.BufferEncoding + +internal actual class Inflater { + private val inflate = Inflate() + + actual fun Frame.inflateData(): String { + val buffer = Buffer.from(data) + + return inflate.process(buffer).toString(BufferEncoding.utf8) + } +} diff --git a/gateway/src/jsMain/kotlin/internal/JsInflater.kt b/gateway/src/jsMain/kotlin/internal/JsInflater.kt new file mode 100644 index 000000000000..7a0b752ddb28 --- /dev/null +++ b/gateway/src/jsMain/kotlin/internal/JsInflater.kt @@ -0,0 +1,11 @@ +@file:JsModule("fast-zlib") +@file:JsNonModule + +package dev.kord.gateway.internal + +import js.typedarrays.Uint8Array +import node.buffer.Buffer + +internal external class Inflate { + fun process(data: Uint8Array): Buffer +} diff --git a/gateway/src/jvmMain/kotlin/DefaultGatewayJvm.kt b/gateway/src/jvmMain/kotlin/DefaultGatewayJvm.kt new file mode 100644 index 000000000000..4394c82a8313 --- /dev/null +++ b/gateway/src/jvmMain/kotlin/DefaultGatewayJvm.kt @@ -0,0 +1,6 @@ +package dev.kord.gateway + +import java.nio.channels.UnresolvedAddressException + +internal actual fun Throwable.isTimeout() = this is UnresolvedAddressException +internal actual val os: String get() = System.getProperty("os.name") diff --git a/gateway/src/jvmMain/kotlin/Inflater.kt b/gateway/src/jvmMain/kotlin/Inflater.kt new file mode 100644 index 000000000000..1884a03ccbfe --- /dev/null +++ b/gateway/src/jvmMain/kotlin/Inflater.kt @@ -0,0 +1,18 @@ +package dev.kord.gateway + +import io.ktor.websocket.* +import java.io.ByteArrayOutputStream +import java.util.zip.InflaterOutputStream + +internal actual class Inflater { + private val delegate = java.util.zip.Inflater() + + actual fun Frame.inflateData(): String { + val outputStream = ByteArrayOutputStream() + InflaterOutputStream(outputStream, delegate).use { + it.write(data) + } + + return outputStream.use { it.toByteArray().decodeToString() } + } +} diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f2e6f14229b6..9da88264431e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -7,7 +7,13 @@ kotlinx-coroutines = "1.6.4" # https://github.com/Kotlin/kotlinx.coroutines kotlinx-serialization = "1.5.0" # https://github.com/Kotlin/kotlinx.serialization kotlinx-datetime = "0.4.0" # https://github.com/Kotlin/kotlinx-datetime kotlin-logging = "3.0.5" # https://github.com/oshai/kotlin-logging -kord-cache = { strictly = "[0.3.0, 0.4.0[", prefer = "latest.release" } +kord-cache = "0.4.0" # https://github.com/kordlib/cache + +# implementation dependencies +kotlinx-nodejs = "18.14.0-pre.502" # https://github.com/JetBrains/kotlin-wrappers +bignum = "0.3.8" # https://github.com/ionspin/kotlin-multiplatform-bignum +stately = "2.0.0-rc1" # https://github.com/touchlab/Stately +fastZlib = "2.0.1" # https://github.com/timotejroiko/fast-zlib # code generation ksp = "1.8.10-1.0.9" # https://github.com/google/ksp @@ -34,29 +40,38 @@ kord-cache-map = { module = "dev.kord.cache:cache-map", version.ref = "kord-cach # ktor ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktor" } ktor-serialization-kotlinx-json = { module = "io.ktor:ktor-serialization-kotlinx-json", version.ref = "ktor" } +ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" } +ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" } ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktor" } ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" } ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" } ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" } +ktor-utils = { module = "io.ktor:ktor-utils", version.ref = "ktor" } # kotlinx kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" } kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" } kotlinx-serialization-json = { module = "org.jetbrains.kotlinx:kotlinx-serialization-json", version.ref = "kotlinx-serialization" } kotlinx-datetime = { module = "org.jetbrains.kotlinx:kotlinx-datetime", version.ref = "kotlinx-datetime" } +kotlinx-nodejs = { module = "org.jetbrains.kotlin-wrappers:kotlin-node", version.ref = "kotlinx-nodejs" } # other kotlin-logging = { module = "io.github.microutils:kotlin-logging", version.ref = "kotlin-logging" } +# JDK replacements +bignum = { module = "com.ionspin.kotlin:bignum", version.ref = "bignum" } +stately-collections = { module = "co.touchlab:stately-concurrent-collections", version.ref = "stately" } + # code generation ksp-api = { module = "com.google.devtools.ksp:symbol-processing-api", version.ref = "ksp" } kotlinpoet = { module = "com.squareup:kotlinpoet", version.ref = "kotlinpoet" } kotlinpoet-ksp = { module = "com.squareup:kotlinpoet-ksp", version.ref = "kotlinpoet" } # tests -kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" } +kotlin-test-annotations-common = { module = "org.jetbrains.kotlin:kotlin-test-annotations-common", version.ref = "kotlin" } +kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test-common", version.ref = "kotlin" } +kotlin-test-js = { module = "org.jetbrains.kotlin:kotlin-test-js", version.ref = "kotlin" } kotlin-test-junit5 = { module = "org.jetbrains.kotlin:kotlin-test-junit5", version.ref = "kotlin" } -junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit5" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit5" } mockk = { module = "io.mockk:mockk", version.ref = "mockk" } slf4j-simple = { module = "org.slf4j:slf4j-simple", version.ref = "slf4j" } @@ -75,8 +90,9 @@ ksp-plugin = { module = "com.google.devtools.ksp:symbol-processing-gradle-plugin ktor-client-serialization = ["ktor-client-content-negotiation", "ktor-serialization-kotlinx-json"] -test-implementation = ["kotlinx-coroutines-test", "kotlin-test", "junit-jupiter-api", "mockk"] -test-runtime = ["kotlin-test-junit5", "junit-jupiter-engine", "slf4j-simple"] +test-common = ["kotlin-test-annotations-common", "kotlin-test", "kotlinx-coroutines-test"] +test-js = ["kotlin-test-js", "kotlinx-nodejs"] +test-jvm = ["kotlin-test-junit5", "junit-jupiter-engine", "slf4j-simple"] pluginsForBuildSrc = [ "kotlin-jvm-plugin", diff --git a/kotlin-js-store/yarn.lock b/kotlin-js-store/yarn.lock new file mode 100644 index 000000000000..1173a5e9c97d --- /dev/null +++ b/kotlin-js-store/yarn.lock @@ -0,0 +1,635 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@js-joda/core@3.2.0": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@js-joda/core/-/core-3.2.0.tgz#3e61e21b7b2b8a6be746df1335cf91d70db2a273" + integrity sha512-PMqgJ0sw5B7FKb2d5bWYIoxjri+QlW/Pys7+Rw82jSH0QN3rB05jZ/VrrsUdh1w4+i2kw9JOejXGq/KhDOX7Kg== + +"@types/node@^18.14.0": + version "18.14.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.1.tgz#90dad8476f1e42797c49d6f8b69aaf9f876fc69f" + integrity sha512-QH+37Qds3E0eDlReeboBxfHbX9omAcBCXEzswCu6jySP642jiM3cYSIkU/REqwhCUqXdonHFuBfJDiAJxMNhaQ== + +"@ungap/promise-all-settled@1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz#aa58042711d6e3275dd37dc597e5d31e8c290a44" + integrity sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q== + +abort-controller@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + +ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + +ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + +anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + +balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + +binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + +braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + +browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + +buffer-from@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + +camelcase@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + +chalk@^4.1.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +chokidar@3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + +color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + +debug@4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + +diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + +dukat@0.5.8-rc.4: + version "0.5.8-rc.4" + resolved "https://registry.yarnpkg.com/dukat/-/dukat-0.5.8-rc.4.tgz#90384dcb50b14c26f0e99dae92b2dea44f5fce21" + integrity sha512-ZnMt6DGBjlVgK2uQamXfd7uP/AxH7RqI0BL9GLrrJb2gKdDxvJChWy+M9AQEaL+7/6TmxzJxFOsRiInY9oGWTA== + dependencies: + google-protobuf "3.12.2" + typescript "3.9.5" + +emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + +escape-string-regexp@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +fast-zlib@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-zlib/-/fast-zlib-2.0.1.tgz#be624f592fc80ad8019ee2025d16a367a4e9b024" + integrity sha512-DCoYgNagM2Bt1VIpXpdGnRx4LzqJeYG0oh6Nf/7cWo6elTXkFGMw9CrRCYYUIapYNrozYMoyDRflx9mgT3Awyw== + +fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + +find-up@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + +format-util@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/format-util/-/format-util-1.0.5.tgz#1ffb450c8a03e7bccffe40643180918cc297d271" + integrity sha512-varLbTj0e0yVyRpqQhuWV+8hlePAgaoFRhNFj50BNjEIrw1/DphHSObtqwskVCPWNgzwPoQrZAbfa/SBiicNeg== + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + +fsevents@~2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" + integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== + +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + +glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + +glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +google-protobuf@3.12.2: + version "3.12.2" + resolved "https://registry.yarnpkg.com/google-protobuf/-/google-protobuf-3.12.2.tgz#50ce9f9b6281235724eb243d6a83e969a2176e53" + integrity sha512-4CZhpuRr1d6HjlyrxoXoocoGFnRYgKULgMtikMddA9ztRyYR59Aondv2FioyxWVamRo0rF2XpYawkTCBEQOSkA== + +has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + +he@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + +is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + +is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + +is-glob@^4.0.1, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + +is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + +is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + +js-yaml@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + +log-symbols@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +mocha@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.0.0.tgz#205447d8993ec755335c4b13deba3d3a13c4def9" + integrity sha512-0Wl+elVUD43Y0BqPZBzZt8Tnkw9CMUdNYnUsTfOM1vuhJVZL+kiesFYsqwBkEEuEixaiPe5ZQdqDgX2jddhmoA== + dependencies: + "@ungap/promise-all-settled" "1.1.2" + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + +ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + +ms@2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + +node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + +once@^1.3.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + +p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + +path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + +picomatch@^2.0.4, picomatch@^2.2.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + +readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + +safe-buffer@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + +source-map-support@0.5.21: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map@^0.6.0: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + +string-width@^4.1.0, string-width@^4.2.0: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-json-comments@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + +supports-color@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + +supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + +to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +typescript@3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.5.tgz#586f0dba300cde8be52dd1ac4f7e1009c1b13f36" + integrity sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ== + +typescript@4.7.4: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + +ws@8.5.0: + version "8.5.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.5.0.tgz#bfb4be96600757fe5382de12c670dab984a1ed4f" + integrity sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + +yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + +yargs@16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== diff --git a/ksp-annotations/build.gradle.kts b/ksp-annotations/build.gradle.kts index e8efcb5ecf8c..f4f0c10edf1c 100644 --- a/ksp-annotations/build.gradle.kts +++ b/ksp-annotations/build.gradle.kts @@ -1,3 +1,13 @@ +import org.jetbrains.dokka.gradle.AbstractDokkaLeafTask + plugins { - `kord-internal-module` + `kord-internal-multiplatform-module` + + // workaround for https://youtrack.jetbrains.com/issue/KT-43500 (not intended to be published) + org.jetbrains.dokka + `kord-publishing` +} + +tasks.withType().configureEach { + enabled = false } diff --git a/ksp-annotations/src/main/kotlin/GenerateKordEnum.kt b/ksp-annotations/src/commonMain/kotlin/GenerateKordEnum.kt similarity index 100% rename from ksp-annotations/src/main/kotlin/GenerateKordEnum.kt rename to ksp-annotations/src/commonMain/kotlin/GenerateKordEnum.kt diff --git a/ksp-processors/src/main/kotlin/KSPUtils.kt b/ksp-processors/src/main/kotlin/KSPUtils.kt index 976d5f0e4617..9764229055cd 100644 --- a/ksp-processors/src/main/kotlin/KSPUtils.kt +++ b/ksp-processors/src/main/kotlin/KSPUtils.kt @@ -15,12 +15,21 @@ internal fun KSAnnotation.isOfType(qualifiedName: String) = shortName.asString() == qualifiedName.substringAfterLast('.') && annotationType.resolve().declaration.qualifiedName?.asString() == qualifiedName -internal class AnnotationArguments private constructor(private val map: Map) { - internal operator fun get(parameter: KProperty1) = map[parameter.name] +internal class AnnotationArguments private constructor(private val map: Map) { + private inline fun get(parameter: KProperty1) = map[parameter.name] as V? + + internal inline fun getSafe(parameter: KProperty1) = + get(parameter) ?: error("Missing required parameter: $parameter") + + // https://github.com/google/ksp/issues/885 + internal inline fun getOrDefault(parameter: KProperty1, defaultValue: V) = + get(parameter) ?: defaultValue + + internal fun getRaw(parameter: KProperty1) = map[parameter.name] internal companion object { internal val KSAnnotation.annotationArguments - get() = AnnotationArguments(arguments.associate { it.name!!.getShortName() to it.value!! }) + get() = AnnotationArguments(arguments.associate { it.name!!.getShortName() to it.value }) } } diff --git a/ksp-processors/src/main/kotlin/kordenum/KordEnum.kt b/ksp-processors/src/main/kotlin/kordenum/KordEnum.kt index 33b8230e8489..e0c90a6cdf62 100644 --- a/ksp-processors/src/main/kotlin/kordenum/KordEnum.kt +++ b/ksp-processors/src/main/kotlin/kordenum/KordEnum.kt @@ -53,16 +53,16 @@ internal class KordEnum( internal fun KSAnnotation.toKordEnumOrNull(logger: KSPLogger): KordEnum? { val args = annotationArguments - val name = args[GenerateKordEnum::name] as String - val valueType = args[GenerateKordEnum::valueType].toValueType() - val entries = args[GenerateKordEnum::entries] as List<*> - val kDoc = args[GenerateKordEnum::kDoc].toKDoc() - val docUrl = (args[GenerateKordEnum::docUrl] as String).ifBlank { null } - val valueName = args[GenerateKordEnum::valueName] as String - val deprecatedEntries = args[GenerateKordEnum::deprecatedEntries] as List<*> - - val valuesPropertyName = (args[GenerateKordEnum::valuesPropertyName] as String).ifEmpty { null } - val valuesPropertyType = args[GenerateKordEnum::valuesPropertyType].toValuesPropertyType() + val name = args.getSafe(GenerateKordEnum::name) + val valueType = args.getRaw(GenerateKordEnum::valueType).toValueType() + val entries = args.getRaw(GenerateKordEnum::entries) as List<*> + val kDoc = args.getOrDefault(GenerateKordEnum::kDoc, "").toKDoc() + val docUrl = args.getOrDefault(GenerateKordEnum::docUrl, "").ifBlank { null } + val valueName = args.getOrDefault(GenerateKordEnum::valueName, "value") + val deprecatedEntries = args.getRaw(GenerateKordEnum::deprecatedEntries) as List<*>? ?: emptyList() + + val valuesPropertyName = args.getOrDefault(GenerateKordEnum::valuesPropertyName, "").ifEmpty { null } + val valuesPropertyType = args.getRaw(GenerateKordEnum::valuesPropertyType)?.toValuesPropertyType() ?: NONE if (valuesPropertyName != null) { if (valuesPropertyType == NONE) { logger.error("Didn't specify valuesPropertyType", symbol = this) @@ -74,7 +74,7 @@ internal fun KSAnnotation.toKordEnumOrNull(logger: KSPLogger): KordEnum? { return null } } - val deprecatedSerializerName = (args[GenerateKordEnum::deprecatedSerializerName] as String).ifEmpty { null } + val deprecatedSerializerName = args.getOrDefault(GenerateKordEnum::deprecatedSerializerName, "").ifEmpty { null } return KordEnum( name, kDoc, docUrl, valueType, valueName, @@ -109,14 +109,14 @@ private fun Any?.toValuesPropertyType() = when (val name = (this as KSType).decl private fun Any?.toEntryOrNull(valueType: ValueType, isDeprecated: Boolean, logger: KSPLogger): Entry? { val args = (this as KSAnnotation).annotationArguments - val name = args[GenerateKordEnum.Entry::name] as String - val intValue = args[GenerateKordEnum.Entry::intValue] as Int - val stringValue = args[GenerateKordEnum.Entry::stringValue] as String - val kDoc = args[GenerateKordEnum.Entry::kDoc].toKDoc() - val isKordExperimental = args[GenerateKordEnum.Entry::isKordExperimental] as Boolean - val deprecationMessage = args[GenerateKordEnum.Entry::deprecationMessage] as String - val replaceWith = args[GenerateKordEnum.Entry::replaceWith].toReplaceWith() - val deprecationLevel = args[GenerateKordEnum.Entry::deprecationLevel].toDeprecationLevel() + val name = args.getSafe(GenerateKordEnum.Entry::name) + val intValue = args.getOrDefault(GenerateKordEnum.Entry::intValue, GenerateKordEnum.Entry.DEFAULT_INT_VALUE) + val stringValue = args.getOrDefault(GenerateKordEnum.Entry::stringValue, GenerateKordEnum.Entry.DEFAULT_STRING_VALUE) + val kDoc = args.getOrDefault(GenerateKordEnum.Entry::kDoc, "").toKDoc() + val isKordExperimental = args.getOrDefault(GenerateKordEnum.Entry::isKordExperimental, false) + val deprecationMessage = args.getOrDefault(GenerateKordEnum.Entry::deprecationMessage, "") + val replaceWith = args.getRaw(GenerateKordEnum.Entry::replaceWith)?.toReplaceWith() ?: ReplaceWith("", imports = emptyArray()) + val deprecationLevel = args.getRaw(GenerateKordEnum.Entry::deprecationLevel)?.toDeprecationLevel() ?: WARNING val value = when (valueType) { INT -> { @@ -172,8 +172,8 @@ private fun Any?.toEntryOrNull(valueType: ValueType, isDeprecated: Boolean, logg private fun Any?.toReplaceWith(): ReplaceWith { val args = (this as KSAnnotation).annotationArguments - val expression = args[ReplaceWith::expression] as String - val imports = @Suppress("UNCHECKED_CAST") (args[ReplaceWith::imports] as List) + val expression = args.getSafe(ReplaceWith::expression) + val imports = @Suppress("UNCHECKED_CAST") (args.getRaw(ReplaceWith::imports) as List) return ReplaceWith(expression, *imports.toTypedArray()) } diff --git a/rest/README.md b/rest/README.md index 59fe8aac2e52..3cef5021b66b 100644 --- a/rest/README.md +++ b/rest/README.md @@ -84,7 +84,7 @@ dependencies { dev.kord - kord-rest + kord-rest-jvm {version} ``` diff --git a/rest/api/rest.api b/rest/api/rest.api index 929ac61b078f..299538983ef8 100644 --- a/rest/api/rest.api +++ b/rest/api/rest.api @@ -58,13 +58,10 @@ public final class dev/kord/rest/Image$Size : java/lang/Enum { public final class dev/kord/rest/NamedFile { public fun (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)V - public synthetic fun (Ljava/lang/String;Ljava/io/InputStream;)V public final fun component1 ()Ljava/lang/String; public final fun component2 ()Lio/ktor/client/request/forms/ChannelProvider; - public final synthetic fun component2 ()Ljava/io/InputStream; public final fun component3 ()Ljava/lang/String; public final fun getContentProvider ()Lio/ktor/client/request/forms/ChannelProvider; - public final synthetic fun getInputStream ()Ljava/io/InputStream; public final fun getName ()Ljava/lang/String; public final fun getUrl ()Ljava/lang/String; } @@ -1082,7 +1079,7 @@ public final class dev/kord/rest/builder/guild/GuildModifyBuilder : dev/kord/res public final fun getName ()Ljava/lang/String; public final fun getNotificationLevel ()Ldev/kord/common/entity/DefaultMessageNotificationLevel; public final fun getOwnerId ()Ldev/kord/common/entity/Snowflake; - public final fun getPreferredLocale ()Ljava/util/Locale; + public final fun getPreferredLocale ()Ldev/kord/common/Locale; public final fun getPublicUpdatesChannelId ()Ldev/kord/common/entity/Snowflake; public fun getReason ()Ljava/lang/String; public final fun getRegion ()Ljava/lang/String; @@ -1099,7 +1096,7 @@ public final class dev/kord/rest/builder/guild/GuildModifyBuilder : dev/kord/res public final fun setName (Ljava/lang/String;)V public final fun setNotificationLevel (Ldev/kord/common/entity/DefaultMessageNotificationLevel;)V public final fun setOwnerId (Ldev/kord/common/entity/Snowflake;)V - public final fun setPreferredLocale (Ljava/util/Locale;)V + public final fun setPreferredLocale (Ldev/kord/common/Locale;)V public final fun setPublicUpdatesChannelId (Ldev/kord/common/entity/Snowflake;)V public fun setReason (Ljava/lang/String;)V public final fun setRegion (Ljava/lang/String;)V @@ -1909,8 +1906,6 @@ public final class dev/kord/rest/builder/message/EmbedBuilder$Thumbnail : dev/ko public final class dev/kord/rest/builder/message/create/FollowupMessageCreateBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/create/MessageCreateBuilder { public fun (Z)V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getComponents ()Ljava/util/List; public fun getContent ()Ljava/lang/String; @@ -1934,8 +1929,6 @@ public final class dev/kord/rest/builder/message/create/FollowupMessageCreateBui public final class dev/kord/rest/builder/message/create/ForumMessageCreateBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/create/MessageCreateBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getComponents ()Ljava/util/List; public fun getContent ()Ljava/lang/String; @@ -1961,8 +1954,6 @@ public final class dev/kord/rest/builder/message/create/InteractionResponseCreat public fun (Z)V public synthetic fun (ZILkotlin/jvm/internal/DefaultConstructorMarker;)V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getComponents ()Ljava/util/List; public fun getContent ()Ljava/lang/String; @@ -1985,8 +1976,6 @@ public final class dev/kord/rest/builder/message/create/InteractionResponseCreat public abstract interface class dev/kord/rest/builder/message/create/MessageCreateBuilder { public abstract fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public abstract synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public abstract fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public abstract fun getComponents ()Ljava/util/List; public abstract fun getContent ()Ljava/lang/String; @@ -2006,8 +1995,10 @@ public abstract interface class dev/kord/rest/builder/message/create/MessageCrea public final class dev/kord/rest/builder/message/create/MessageCreateBuilder$DefaultImpls { public static fun addFile (Ldev/kord/rest/builder/message/create/MessageCreateBuilder;Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public static synthetic fun addFile (Ldev/kord/rest/builder/message/create/MessageCreateBuilder;Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public static fun addFile (Ldev/kord/rest/builder/message/create/MessageCreateBuilder;Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class dev/kord/rest/builder/message/create/MessageCreateBuilderJvmKt { + public static final fun addFile (Ldev/kord/rest/builder/message/create/MessageCreateBuilder;Ljava/nio/file/Path;)Ldev/kord/rest/NamedFile; } public final class dev/kord/rest/builder/message/create/MessageCreateBuilderKt { @@ -2021,8 +2012,6 @@ public final class dev/kord/rest/builder/message/create/MessageCreateBuilderKt { public final class dev/kord/rest/builder/message/create/UpdateMessageInteractionResponseCreateBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/create/MessageCreateBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getComponents ()Ljava/util/List; public fun getContent ()Ljava/lang/String; @@ -2048,8 +2037,6 @@ public final class dev/kord/rest/builder/message/create/UpdateMessageInteraction public final class dev/kord/rest/builder/message/create/UserMessageCreateBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/create/MessageCreateBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getComponents ()Ljava/util/List; public fun getContent ()Ljava/lang/String; @@ -2078,8 +2065,6 @@ public final class dev/kord/rest/builder/message/create/UserMessageCreateBuilder public final class dev/kord/rest/builder/message/create/WebhookMessageCreateBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/create/MessageCreateBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public final fun getAvatarUrl ()Ljava/lang/String; public fun getComponents ()Ljava/util/List; @@ -2108,8 +2093,6 @@ public final class dev/kord/rest/builder/message/create/WebhookMessageCreateBuil public final class dev/kord/rest/builder/message/modify/FollowupMessageModifyBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/modify/MessageModifyBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getAttachments ()Ljava/util/List; public fun getComponents ()Ljava/util/List; @@ -2133,8 +2116,6 @@ public final class dev/kord/rest/builder/message/modify/FollowupMessageModifyBui public final class dev/kord/rest/builder/message/modify/InteractionResponseModifyBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/modify/MessageModifyBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getAttachments ()Ljava/util/List; public fun getComponents ()Ljava/util/List; @@ -2157,8 +2138,6 @@ public final class dev/kord/rest/builder/message/modify/InteractionResponseModif public abstract interface class dev/kord/rest/builder/message/modify/MessageModifyBuilder { public abstract fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public abstract synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public abstract fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public abstract fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public abstract fun getAttachments ()Ljava/util/List; public abstract fun getComponents ()Ljava/util/List; @@ -2179,8 +2158,10 @@ public abstract interface class dev/kord/rest/builder/message/modify/MessageModi public final class dev/kord/rest/builder/message/modify/MessageModifyBuilder$DefaultImpls { public static fun addFile (Ldev/kord/rest/builder/message/modify/MessageModifyBuilder;Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public static synthetic fun addFile (Ldev/kord/rest/builder/message/modify/MessageModifyBuilder;Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public static fun addFile (Ldev/kord/rest/builder/message/modify/MessageModifyBuilder;Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; +} + +public final class dev/kord/rest/builder/message/modify/MessageModifyBuilderJvmKt { + public static final fun addFile (Ldev/kord/rest/builder/message/modify/MessageModifyBuilder;Ljava/nio/file/Path;)Ldev/kord/rest/NamedFile; } public final class dev/kord/rest/builder/message/modify/MessageModifyBuilderKt { @@ -2194,8 +2175,6 @@ public final class dev/kord/rest/builder/message/modify/MessageModifyBuilderKt { public final class dev/kord/rest/builder/message/modify/UserMessageModifyBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/modify/MessageModifyBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getAttachments ()Ljava/util/List; public fun getComponents ()Ljava/util/List; @@ -2219,8 +2198,6 @@ public final class dev/kord/rest/builder/message/modify/UserMessageModifyBuilder public final class dev/kord/rest/builder/message/modify/WebhookMessageModifyBuilder : dev/kord/rest/builder/RequestBuilder, dev/kord/rest/builder/message/modify/MessageModifyBuilder { public fun ()V public fun addFile (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)Ldev/kord/rest/NamedFile; - public synthetic fun addFile (Ljava/lang/String;Ljava/io/InputStream;)Ldev/kord/rest/NamedFile; - public fun addFile (Ljava/nio/file/Path;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; public fun getAllowedMentions ()Ldev/kord/rest/builder/message/AllowedMentionsBuilder; public fun getAttachments ()Ljava/util/List; public fun getComponents ()Ljava/util/List; @@ -6058,8 +6035,6 @@ public final class dev/kord/rest/request/RequestBuilder { public final fun build ()Ldev/kord/rest/request/Request; public final fun file (Ldev/kord/rest/NamedFile;)V public final fun file (Ljava/lang/String;Lio/ktor/client/request/forms/ChannelProvider;)V - public final synthetic fun file (Ljava/lang/String;Ljava/io/InputStream;)V - public final fun file (Ljava/nio/file/Path;)V public final fun getBaseUrl ()Ljava/lang/String; public final fun getKeys ()Ljava/util/Map; public final fun getRoute ()Ldev/kord/rest/route/Route; @@ -6072,6 +6047,10 @@ public final class dev/kord/rest/request/RequestBuilder { public final fun urlEncodedHeader (Ljava/lang/String;Ljava/lang/String;)V } +public final class dev/kord/rest/request/RequestBuilderKt { + public static final fun file (Ldev/kord/rest/request/RequestBuilder;Ljava/nio/file/Path;)V +} + public abstract interface class dev/kord/rest/request/RequestHandler { public abstract fun getToken ()Ljava/lang/String; public abstract fun handle (Ldev/kord/rest/request/Request;Lkotlin/coroutines/Continuation;)Ljava/lang/Object; diff --git a/rest/build.gradle.kts b/rest/build.gradle.kts index cfdf92efda3d..21202494c784 100644 --- a/rest/build.gradle.kts +++ b/rest/build.gradle.kts @@ -1,18 +1,21 @@ plugins { - `kord-module` - `kord-sampled-module` + `kord-multiplatform-module` `kord-publishing` } -dependencies { - api(projects.common) +kotlin { + sourceSets { + commonMain { + dependencies { + api(projects.common) - api(libs.bundles.ktor.client.serialization) - api(libs.ktor.client.cio) - - ksp(projects.kspProcessors) - - testImplementation(libs.bundles.test.implementation) - testImplementation(libs.ktor.client.mock) - testRuntimeOnly(libs.bundles.test.runtime) + api(libs.bundles.ktor.client.serialization) + } + } + commonTest { + dependencies { + implementation(libs.ktor.client.mock) + } + } + } } diff --git a/rest/src/main/kotlin/Image.kt b/rest/src/commonMain/kotlin/Image.kt similarity index 94% rename from rest/src/main/kotlin/Image.kt rename to rest/src/commonMain/kotlin/Image.kt index fa2d76f94f28..1ec1ee4a6f73 100644 --- a/rest/src/main/kotlin/Image.kt +++ b/rest/src/commonMain/kotlin/Image.kt @@ -4,7 +4,6 @@ import io.ktor.client.* import io.ktor.client.call.* import io.ktor.client.request.* import io.ktor.util.* -import kotlinx.coroutines.Dispatchers public class Image private constructor(public val data: ByteArray, public val format: Format) { @@ -15,14 +14,14 @@ public class Image private constructor(public val data: ByteArray, public val fo return Image(data, format) } - public suspend fun fromUrl(client: HttpClient, url: String): Image = with(Dispatchers.IO) { + public suspend fun fromUrl(client: HttpClient, url: String): Image { val call = client.get(url) val contentType = call.headers["Content-Type"] ?: error("expected 'Content-Type' header in image request") val bytes = call.body() - Image(bytes, Format.fromContentType(contentType)) + return Image(bytes, Format.fromContentType(contentType)) } } diff --git a/rest/src/commonMain/kotlin/NamedFile.kt b/rest/src/commonMain/kotlin/NamedFile.kt new file mode 100644 index 000000000000..8ec177f408e6 --- /dev/null +++ b/rest/src/commonMain/kotlin/NamedFile.kt @@ -0,0 +1,12 @@ +package dev.kord.rest + +import io.ktor.client.request.forms.* + +public class NamedFile(public val name: String, public val contentProvider: ChannelProvider) { + + public val url: String get() = "attachment://$name" + + public operator fun component1(): String = name + public operator fun component2(): ChannelProvider = contentProvider + public operator fun component3(): String = url +} diff --git a/rest/src/main/kotlin/builder/RequestBuilder.kt b/rest/src/commonMain/kotlin/builder/RequestBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/RequestBuilder.kt rename to rest/src/commonMain/kotlin/builder/RequestBuilder.kt diff --git a/rest/src/main/kotlin/builder/auditlog/AuditLogGetRequestBuilder.kt b/rest/src/commonMain/kotlin/builder/auditlog/AuditLogGetRequestBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/auditlog/AuditLogGetRequestBuilder.kt rename to rest/src/commonMain/kotlin/builder/auditlog/AuditLogGetRequestBuilder.kt diff --git a/rest/src/main/kotlin/builder/automoderation/AutoModerationActionBuilder.kt b/rest/src/commonMain/kotlin/builder/automoderation/AutoModerationActionBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/automoderation/AutoModerationActionBuilder.kt rename to rest/src/commonMain/kotlin/builder/automoderation/AutoModerationActionBuilder.kt diff --git a/rest/src/main/kotlin/builder/automoderation/AutoModerationRuleBuilder.kt b/rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/automoderation/AutoModerationRuleBuilder.kt rename to rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleBuilder.kt diff --git a/rest/src/main/kotlin/builder/automoderation/AutoModerationRuleCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/automoderation/AutoModerationRuleCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/automoderation/AutoModerationRuleModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/automoderation/AutoModerationRuleModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/automoderation/AutoModerationRuleModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/ban/BanCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/ban/BanCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/ban/BanCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/ban/BanCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/CategoryCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/CategoryCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/CategoryCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/CategoryCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/CategoryModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/CategoryModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/CategoryModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/ChannelPermissionModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/ChannelPermissionModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/ChannelPermissionModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/ChannelPermissionModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/EditGuildChannelBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/EditGuildChannelBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/EditGuildChannelBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/ForumChannelCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/ForumChannelCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/ForumChannelCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/ForumChannelCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/GuildChannelPositionModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/InviteCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/InviteCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/InviteCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/InviteCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/NewsChannelCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/NewsChannelCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/NewsChannelCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/NewsChannelCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/PermissionOverwriteBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/PermissionOverwriteBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/PermissionOverwriteBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/PermissionOverwriteBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/PermissionOverwritesBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/PermissionOverwritesBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/PermissionOverwritesBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/PermissionOverwritesBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/TextChannelCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/TextChannelCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/TextChannelCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/TextChannelCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/VoiceChannelCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/VoiceChannelCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/VoiceChannelCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/VoiceChannelCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/thread/StartForumThreadBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/thread/StartForumThreadBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/thread/StartForumThreadBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/thread/StartForumThreadBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/thread/StartThreadBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/thread/StartThreadBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/thread/StartThreadBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/thread/StartThreadBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/thread/StartThreadWithMessageBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/thread/StartThreadWithMessageBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/thread/StartThreadWithMessageBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/thread/StartThreadWithMessageBuilder.kt diff --git a/rest/src/main/kotlin/builder/channel/thread/ThreadModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/channel/thread/ThreadModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/channel/thread/ThreadModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/channel/thread/ThreadModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/component/ActionRowBuilder.kt b/rest/src/commonMain/kotlin/builder/component/ActionRowBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/ActionRowBuilder.kt rename to rest/src/commonMain/kotlin/builder/component/ActionRowBuilder.kt diff --git a/rest/src/main/kotlin/builder/component/ButtonBuilder.kt b/rest/src/commonMain/kotlin/builder/component/ButtonBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/ButtonBuilder.kt rename to rest/src/commonMain/kotlin/builder/component/ButtonBuilder.kt diff --git a/rest/src/main/kotlin/builder/component/ComponentBuilders.kt b/rest/src/commonMain/kotlin/builder/component/ComponentBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/ComponentBuilders.kt rename to rest/src/commonMain/kotlin/builder/component/ComponentBuilders.kt diff --git a/rest/src/main/kotlin/builder/component/SelectMenuBuilder.kt b/rest/src/commonMain/kotlin/builder/component/SelectMenuBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/SelectMenuBuilder.kt rename to rest/src/commonMain/kotlin/builder/component/SelectMenuBuilder.kt diff --git a/rest/src/main/kotlin/builder/component/SelectOptionBuilder.kt b/rest/src/commonMain/kotlin/builder/component/SelectOptionBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/SelectOptionBuilder.kt rename to rest/src/commonMain/kotlin/builder/component/SelectOptionBuilder.kt diff --git a/rest/src/main/kotlin/builder/component/TextInputBuilder.kt b/rest/src/commonMain/kotlin/builder/component/TextInputBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/component/TextInputBuilder.kt rename to rest/src/commonMain/kotlin/builder/component/TextInputBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/EmojiCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/EmojiCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/EmojiCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/EmojiCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/EmojiModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/EmojiModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/EmojiModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/EmojiModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/GuildCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/GuildCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/GuildCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/GuildCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/GuildModifyBuilder.kt similarity index 96% rename from rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/GuildModifyBuilder.kt index ad3c81c10fc3..d03ea1c812e2 100644 --- a/rest/src/main/kotlin/builder/guild/GuildModifyBuilder.kt +++ b/rest/src/commonMain/kotlin/builder/guild/GuildModifyBuilder.kt @@ -1,5 +1,6 @@ package dev.kord.rest.builder.guild +import dev.kord.common.Locale import dev.kord.common.annotation.KordDsl import dev.kord.common.entity.* import dev.kord.common.entity.optional.Optional @@ -9,7 +10,6 @@ import dev.kord.common.entity.optional.map import dev.kord.rest.Image import dev.kord.rest.builder.AuditRequestBuilder import dev.kord.rest.json.request.GuildModifyRequest -import java.util.* import kotlin.time.Duration @KordDsl @@ -94,7 +94,7 @@ public class GuildModifyBuilder : AuditRequestBuilder { _systemChannelId, _rulesChannelId, _publicUpdatesChannelId, - _preferredLocale.map { "${it.language}-${it.country}" }, + _preferredLocale.map { locale -> "${locale.language}${locale.country?.let { "-$it" } ?: ""}" }, features = _features, ) } diff --git a/rest/src/main/kotlin/builder/guild/ScheduledEventCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/ScheduledEventCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/ScheduledEventCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/ScheduledEventCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/StickerModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/StickerModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/StickerModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/StickerModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/VoiceStateModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/VoiceStateModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/VoiceStateModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/VoiceStateModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/WelcomeScreenModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/WelcomeScreenModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/WelcomeScreenModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/WelcomeScreenModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/guild/WidgetModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/guild/WidgetModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/guild/WidgetModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/guild/WidgetModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/integration/IntegrationModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/integration/IntegrationModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/integration/IntegrationModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/integration/IntegrationModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/interaction/ApplicationCommandBuilders.kt b/rest/src/commonMain/kotlin/builder/interaction/ApplicationCommandBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/ApplicationCommandBuilders.kt rename to rest/src/commonMain/kotlin/builder/interaction/ApplicationCommandBuilders.kt diff --git a/rest/src/main/kotlin/builder/interaction/ApplicationCommandStateHolder.kt b/rest/src/commonMain/kotlin/builder/interaction/ApplicationCommandStateHolder.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/ApplicationCommandStateHolder.kt rename to rest/src/commonMain/kotlin/builder/interaction/ApplicationCommandStateHolder.kt diff --git a/rest/src/main/kotlin/builder/interaction/InputChatBuilders.kt b/rest/src/commonMain/kotlin/builder/interaction/InputChatBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/InputChatBuilders.kt rename to rest/src/commonMain/kotlin/builder/interaction/InputChatBuilders.kt diff --git a/rest/src/main/kotlin/builder/interaction/Localization.kt b/rest/src/commonMain/kotlin/builder/interaction/Localization.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/Localization.kt rename to rest/src/commonMain/kotlin/builder/interaction/Localization.kt diff --git a/rest/src/main/kotlin/builder/interaction/MessageCommandBuilders.kt b/rest/src/commonMain/kotlin/builder/interaction/MessageCommandBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/MessageCommandBuilders.kt rename to rest/src/commonMain/kotlin/builder/interaction/MessageCommandBuilders.kt diff --git a/rest/src/main/kotlin/builder/interaction/ModalBuilder.kt b/rest/src/commonMain/kotlin/builder/interaction/ModalBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/ModalBuilder.kt rename to rest/src/commonMain/kotlin/builder/interaction/ModalBuilder.kt diff --git a/rest/src/main/kotlin/builder/interaction/MultiApplicationCommandBuilder.kt b/rest/src/commonMain/kotlin/builder/interaction/MultiApplicationCommandBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/MultiApplicationCommandBuilder.kt rename to rest/src/commonMain/kotlin/builder/interaction/MultiApplicationCommandBuilder.kt diff --git a/rest/src/main/kotlin/builder/interaction/OptionsBuilder.kt b/rest/src/commonMain/kotlin/builder/interaction/OptionsBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/OptionsBuilder.kt rename to rest/src/commonMain/kotlin/builder/interaction/OptionsBuilder.kt diff --git a/rest/src/main/kotlin/builder/interaction/UserCommandBuilders.kt b/rest/src/commonMain/kotlin/builder/interaction/UserCommandBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/interaction/UserCommandBuilders.kt rename to rest/src/commonMain/kotlin/builder/interaction/UserCommandBuilders.kt diff --git a/rest/src/main/kotlin/builder/member/MemberAddBuilder.kt b/rest/src/commonMain/kotlin/builder/member/MemberAddBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/member/MemberAddBuilder.kt rename to rest/src/commonMain/kotlin/builder/member/MemberAddBuilder.kt diff --git a/rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/member/MemberModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/member/MemberModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/member/MemberModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/AllowedMentionsBuilder.kt b/rest/src/commonMain/kotlin/builder/message/AllowedMentionsBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/AllowedMentionsBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/AllowedMentionsBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/EmbedBuilder.kt b/rest/src/commonMain/kotlin/builder/message/EmbedBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/EmbedBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/EmbedBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/FollowupMessageCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/FollowupMessageCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/FollowupMessageCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/FollowupMessageCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/ForumMessageCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/ForumMessageCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/ForumMessageCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/ForumMessageCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/InteractionResponseCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/InteractionResponseCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/InteractionResponseCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/InteractionResponseCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/MessageCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/MessageCreateBuilder.kt similarity index 79% rename from rest/src/main/kotlin/builder/message/create/MessageCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/MessageCreateBuilder.kt index 025edaf7cf67..d7b28c95dab6 100644 --- a/rest/src/main/kotlin/builder/message/create/MessageCreateBuilder.kt +++ b/rest/src/commonMain/kotlin/builder/message/create/MessageCreateBuilder.kt @@ -10,11 +10,6 @@ import dev.kord.rest.builder.component.MessageComponentBuilder import dev.kord.rest.builder.message.AllowedMentionsBuilder import dev.kord.rest.builder.message.EmbedBuilder import io.ktor.client.request.forms.* -import io.ktor.util.cio.* -import io.ktor.utils.io.jvm.javaio.* -import java.io.InputStream -import java.nio.file.Path -import kotlin.DeprecationLevel.HIDDEN import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -74,25 +69,6 @@ public sealed interface MessageCreateBuilder { */ public var suppressNotifications: Boolean? - /** - * Adds a file with the [name] and [content] to the attachments. - * - * @suppress - */ - @Deprecated( - "Use lazy ChannelProvider instead of InputStream. You should also make sure that the stream/channel is only " + - "opened inside the block of the ChannelProvider because it could otherwise be read multiple times " + - "(which isn't allowed).", - ReplaceWith( - "addFile(name, ChannelProvider { content.toByteReadChannel() })", - "io.ktor.client.request.forms.ChannelProvider", - "io.ktor.utils.io.jvm.javaio.toByteReadChannel", - ), - level = HIDDEN, - ) - public fun addFile(name: String, content: InputStream): NamedFile = - addFile(name, ChannelProvider { content.toByteReadChannel() }) - /** * Adds a file with the [name] and [contentProvider] to the attachments. */ @@ -101,13 +77,6 @@ public sealed interface MessageCreateBuilder { files += namedFile return namedFile } - - /** - * Adds a file with the given [path] to the attachments. - */ - public suspend fun addFile(path: Path): NamedFile = - addFile(path.fileName.toString(), ChannelProvider { path.readChannel() }) - } internal fun buildMessageFlags( diff --git a/rest/src/main/kotlin/builder/message/create/UpdateMessageInteractionResponseCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/UpdateMessageInteractionResponseCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/UpdateMessageInteractionResponseCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/UpdateMessageInteractionResponseCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/UserMessageCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/UserMessageCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/UserMessageCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/UserMessageCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/create/WebhookMessageCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/message/create/WebhookMessageCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/create/WebhookMessageCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/create/WebhookMessageCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/modify/FollowupMessageModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/message/modify/FollowupMessageModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/modify/FollowupMessageModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/FollowupMessageModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/modify/InteractionResponseModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/message/modify/InteractionResponseModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/modify/InteractionResponseModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/InteractionResponseModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/modify/MessageModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/message/modify/MessageModifyBuilder.kt similarity index 72% rename from rest/src/main/kotlin/builder/message/modify/MessageModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/MessageModifyBuilder.kt index f3706c866517..1fa4ce0b6153 100644 --- a/rest/src/main/kotlin/builder/message/modify/MessageModifyBuilder.kt +++ b/rest/src/commonMain/kotlin/builder/message/modify/MessageModifyBuilder.kt @@ -10,11 +10,6 @@ import dev.kord.rest.builder.component.MessageComponentBuilder import dev.kord.rest.builder.message.AllowedMentionsBuilder import dev.kord.rest.builder.message.EmbedBuilder import io.ktor.client.request.forms.* -import io.ktor.util.cio.* -import io.ktor.utils.io.jvm.javaio.* -import java.io.InputStream -import java.nio.file.Path -import kotlin.DeprecationLevel.HIDDEN import kotlin.contracts.InvocationKind import kotlin.contracts.contract @@ -49,31 +44,6 @@ public sealed interface MessageModifyBuilder { */ public var suppressEmbeds: Boolean? - /** - * Adds a file with the [name] and [content] to the attachments. - * - * @suppress - */ - @Deprecated( - "Use lazy ChannelProvider instead of InputStream. You should also make sure that the stream/channel is only " + - "opened inside the block of the ChannelProvider because it could otherwise be read multiple times " + - "(which isn't allowed).", - ReplaceWith( - "addFile(name, ChannelProvider { content.toByteReadChannel() })", - "io.ktor.client.request.forms.ChannelProvider", - "io.ktor.utils.io.jvm.javaio.toByteReadChannel", - ), - level = HIDDEN, - ) - public fun addFile(name: String, content: InputStream): NamedFile = - addFile(name, ChannelProvider { content.toByteReadChannel() }) - - /** - * Adds a file with the given [path] to the attachments. - */ - public suspend fun addFile(path: Path): NamedFile = - addFile(path.fileName.toString(), ChannelProvider { path.readChannel() }) - /** * Adds a file with the [name] and [contentProvider] to the attachments. */ diff --git a/rest/src/main/kotlin/builder/message/modify/MessageModifyStateHolder.kt b/rest/src/commonMain/kotlin/builder/message/modify/MessageModifyStateHolder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/modify/MessageModifyStateHolder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/MessageModifyStateHolder.kt diff --git a/rest/src/main/kotlin/builder/message/modify/UserMessageModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/message/modify/UserMessageModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/modify/UserMessageModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/UserMessageModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/message/modify/WebhookMessageModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/message/modify/WebhookMessageModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/message/modify/WebhookMessageModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/message/modify/WebhookMessageModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/role/RoleCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/role/RoleCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/role/RoleCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/role/RoleCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/role/RoleModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/role/RoleModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/role/RoleModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/role/RolePositionsModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/role/RolePositionsModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/role/RolePositionsModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/role/RolePositionsModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/scheduled_events/ScheduledEventModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/scheduled_events/ScheduledEventModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/scheduled_events/ScheduledEventModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/scheduled_events/ScheduledEventModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/stage/StageInstanceCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/stage/StageInstanceCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/stage/StageInstanceCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/stage/StageInstanceCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/stage/StageInstanceModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/stage/StageInstanceModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/stage/StageInstanceModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/stage/StageInstanceModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/template/TemplateBuilders.kt b/rest/src/commonMain/kotlin/builder/template/TemplateBuilders.kt similarity index 100% rename from rest/src/main/kotlin/builder/template/TemplateBuilders.kt rename to rest/src/commonMain/kotlin/builder/template/TemplateBuilders.kt diff --git a/rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/user/CurrentUserModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/user/CurrentUserModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/user/CurrentUserModifyBuilder.kt diff --git a/rest/src/main/kotlin/builder/user/GroupDMCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/user/GroupDMCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/user/GroupDMCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/user/GroupDMCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/webhook/WebhookCreateBuilder.kt b/rest/src/commonMain/kotlin/builder/webhook/WebhookCreateBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/webhook/WebhookCreateBuilder.kt rename to rest/src/commonMain/kotlin/builder/webhook/WebhookCreateBuilder.kt diff --git a/rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt b/rest/src/commonMain/kotlin/builder/webhook/WebhookModifyBuilder.kt similarity index 100% rename from rest/src/main/kotlin/builder/webhook/WebhookModifyBuilder.kt rename to rest/src/commonMain/kotlin/builder/webhook/WebhookModifyBuilder.kt diff --git a/rest/src/main/kotlin/json/JsonErrorCode.kt b/rest/src/commonMain/kotlin/json/JsonErrorCode.kt similarity index 100% rename from rest/src/main/kotlin/json/JsonErrorCode.kt rename to rest/src/commonMain/kotlin/json/JsonErrorCode.kt diff --git a/rest/src/main/kotlin/json/request/AuditLogGetRequest.kt b/rest/src/commonMain/kotlin/json/request/AuditLogGetRequest.kt similarity index 100% rename from rest/src/main/kotlin/json/request/AuditLogGetRequest.kt rename to rest/src/commonMain/kotlin/json/request/AuditLogGetRequest.kt diff --git a/rest/src/main/kotlin/json/request/AutoModerationRequests.kt b/rest/src/commonMain/kotlin/json/request/AutoModerationRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/AutoModerationRequests.kt rename to rest/src/commonMain/kotlin/json/request/AutoModerationRequests.kt diff --git a/rest/src/main/kotlin/json/request/ChannelFollowRequest.kt b/rest/src/commonMain/kotlin/json/request/ChannelFollowRequest.kt similarity index 100% rename from rest/src/main/kotlin/json/request/ChannelFollowRequest.kt rename to rest/src/commonMain/kotlin/json/request/ChannelFollowRequest.kt diff --git a/rest/src/main/kotlin/json/request/ChannelRequests.kt b/rest/src/commonMain/kotlin/json/request/ChannelRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/ChannelRequests.kt rename to rest/src/commonMain/kotlin/json/request/ChannelRequests.kt diff --git a/rest/src/main/kotlin/json/request/EmojiRequests.kt b/rest/src/commonMain/kotlin/json/request/EmojiRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/EmojiRequests.kt rename to rest/src/commonMain/kotlin/json/request/EmojiRequests.kt diff --git a/rest/src/main/kotlin/json/request/GuildRequests.kt b/rest/src/commonMain/kotlin/json/request/GuildRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/GuildRequests.kt rename to rest/src/commonMain/kotlin/json/request/GuildRequests.kt diff --git a/rest/src/main/kotlin/json/request/InteractionsRequests.kt b/rest/src/commonMain/kotlin/json/request/InteractionsRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/InteractionsRequests.kt rename to rest/src/commonMain/kotlin/json/request/InteractionsRequests.kt diff --git a/rest/src/main/kotlin/json/request/InviteCreateRequest.kt b/rest/src/commonMain/kotlin/json/request/InviteCreateRequest.kt similarity index 100% rename from rest/src/main/kotlin/json/request/InviteCreateRequest.kt rename to rest/src/commonMain/kotlin/json/request/InviteCreateRequest.kt diff --git a/rest/src/main/kotlin/json/request/MessageRequests.kt b/rest/src/commonMain/kotlin/json/request/MessageRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/MessageRequests.kt rename to rest/src/commonMain/kotlin/json/request/MessageRequests.kt diff --git a/rest/src/main/kotlin/json/request/ScheduledEventRequests.kt b/rest/src/commonMain/kotlin/json/request/ScheduledEventRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/ScheduledEventRequests.kt rename to rest/src/commonMain/kotlin/json/request/ScheduledEventRequests.kt diff --git a/rest/src/main/kotlin/json/request/StageInstanceRequests.kt b/rest/src/commonMain/kotlin/json/request/StageInstanceRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/StageInstanceRequests.kt rename to rest/src/commonMain/kotlin/json/request/StageInstanceRequests.kt diff --git a/rest/src/main/kotlin/json/request/StickerRequests.kt b/rest/src/commonMain/kotlin/json/request/StickerRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/StickerRequests.kt rename to rest/src/commonMain/kotlin/json/request/StickerRequests.kt diff --git a/rest/src/main/kotlin/json/request/TemplateRequests.kt b/rest/src/commonMain/kotlin/json/request/TemplateRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/TemplateRequests.kt rename to rest/src/commonMain/kotlin/json/request/TemplateRequests.kt diff --git a/rest/src/main/kotlin/json/request/UserRequests.kt b/rest/src/commonMain/kotlin/json/request/UserRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/UserRequests.kt rename to rest/src/commonMain/kotlin/json/request/UserRequests.kt diff --git a/rest/src/main/kotlin/json/request/VoiceStateRequests.kt b/rest/src/commonMain/kotlin/json/request/VoiceStateRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/VoiceStateRequests.kt rename to rest/src/commonMain/kotlin/json/request/VoiceStateRequests.kt diff --git a/rest/src/main/kotlin/json/request/WebhookRequests.kt b/rest/src/commonMain/kotlin/json/request/WebhookRequests.kt similarity index 100% rename from rest/src/main/kotlin/json/request/WebhookRequests.kt rename to rest/src/commonMain/kotlin/json/request/WebhookRequests.kt diff --git a/rest/src/main/kotlin/json/response/BanResponse.kt b/rest/src/commonMain/kotlin/json/response/BanResponse.kt similarity index 100% rename from rest/src/main/kotlin/json/response/BanResponse.kt rename to rest/src/commonMain/kotlin/json/response/BanResponse.kt diff --git a/rest/src/main/kotlin/json/response/Channel.kt b/rest/src/commonMain/kotlin/json/response/Channel.kt similarity index 100% rename from rest/src/main/kotlin/json/response/Channel.kt rename to rest/src/commonMain/kotlin/json/response/Channel.kt diff --git a/rest/src/main/kotlin/json/response/Connection.kt b/rest/src/commonMain/kotlin/json/response/Connection.kt similarity index 100% rename from rest/src/main/kotlin/json/response/Connection.kt rename to rest/src/commonMain/kotlin/json/response/Connection.kt diff --git a/rest/src/main/kotlin/json/response/CurrentUserNicknameModifyResponse.kt b/rest/src/commonMain/kotlin/json/response/CurrentUserNicknameModifyResponse.kt similarity index 100% rename from rest/src/main/kotlin/json/response/CurrentUserNicknameModifyResponse.kt rename to rest/src/commonMain/kotlin/json/response/CurrentUserNicknameModifyResponse.kt diff --git a/rest/src/main/kotlin/json/response/DiscordErrorResponse.kt b/rest/src/commonMain/kotlin/json/response/DiscordErrorResponse.kt similarity index 100% rename from rest/src/main/kotlin/json/response/DiscordErrorResponse.kt rename to rest/src/commonMain/kotlin/json/response/DiscordErrorResponse.kt diff --git a/rest/src/main/kotlin/json/response/FollowedChannelResponse.kt b/rest/src/commonMain/kotlin/json/response/FollowedChannelResponse.kt similarity index 100% rename from rest/src/main/kotlin/json/response/FollowedChannelResponse.kt rename to rest/src/commonMain/kotlin/json/response/FollowedChannelResponse.kt diff --git a/rest/src/main/kotlin/json/response/Gateway.kt b/rest/src/commonMain/kotlin/json/response/Gateway.kt similarity index 100% rename from rest/src/main/kotlin/json/response/Gateway.kt rename to rest/src/commonMain/kotlin/json/response/Gateway.kt diff --git a/rest/src/main/kotlin/json/response/GuildMFALevelModifyResponse.kt b/rest/src/commonMain/kotlin/json/response/GuildMFALevelModifyResponse.kt similarity index 100% rename from rest/src/main/kotlin/json/response/GuildMFALevelModifyResponse.kt rename to rest/src/commonMain/kotlin/json/response/GuildMFALevelModifyResponse.kt diff --git a/rest/src/main/kotlin/json/response/Prune.kt b/rest/src/commonMain/kotlin/json/response/Prune.kt similarity index 100% rename from rest/src/main/kotlin/json/response/Prune.kt rename to rest/src/commonMain/kotlin/json/response/Prune.kt diff --git a/rest/src/main/kotlin/ratelimit/AbstractRateLimiter.kt b/rest/src/commonMain/kotlin/ratelimit/AbstractRateLimiter.kt similarity index 98% rename from rest/src/main/kotlin/ratelimit/AbstractRateLimiter.kt rename to rest/src/commonMain/kotlin/ratelimit/AbstractRateLimiter.kt index 08d31e2577bc..d42d7bbcdbc5 100644 --- a/rest/src/main/kotlin/ratelimit/AbstractRateLimiter.kt +++ b/rest/src/commonMain/kotlin/ratelimit/AbstractRateLimiter.kt @@ -1,5 +1,6 @@ package dev.kord.rest.ratelimit +import dev.kord.common.ConcurrentHashMap import dev.kord.common.ratelimit.IntervalRateLimiter import dev.kord.rest.request.Request import dev.kord.rest.request.RequestIdentifier @@ -11,10 +12,8 @@ import kotlinx.coroutines.delay import kotlinx.coroutines.sync.Mutex import kotlinx.datetime.Clock import mu.KLogger -import java.util.concurrent.ConcurrentHashMap import kotlin.time.Duration.Companion.minutes - public abstract class AbstractRateLimiter internal constructor(public val clock: Clock) : RequestRateLimiter { internal abstract val logger: KLogger diff --git a/rest/src/main/kotlin/ratelimit/ExclusionRequestRateLimiter.kt b/rest/src/commonMain/kotlin/ratelimit/ExclusionRequestRateLimiter.kt similarity index 100% rename from rest/src/main/kotlin/ratelimit/ExclusionRequestRateLimiter.kt rename to rest/src/commonMain/kotlin/ratelimit/ExclusionRequestRateLimiter.kt diff --git a/rest/src/main/kotlin/ratelimit/ParallelRequestRateLimiter.kt b/rest/src/commonMain/kotlin/ratelimit/ParallelRequestRateLimiter.kt similarity index 100% rename from rest/src/main/kotlin/ratelimit/ParallelRequestRateLimiter.kt rename to rest/src/commonMain/kotlin/ratelimit/ParallelRequestRateLimiter.kt diff --git a/rest/src/main/kotlin/ratelimit/RequestRateLimiter.kt b/rest/src/commonMain/kotlin/ratelimit/RequestRateLimiter.kt similarity index 99% rename from rest/src/main/kotlin/ratelimit/RequestRateLimiter.kt rename to rest/src/commonMain/kotlin/ratelimit/RequestRateLimiter.kt index 7ad15688e1e0..02580df0ba27 100644 --- a/rest/src/main/kotlin/ratelimit/RequestRateLimiter.kt +++ b/rest/src/commonMain/kotlin/ratelimit/RequestRateLimiter.kt @@ -4,6 +4,7 @@ import dev.kord.rest.request.Request import kotlinx.datetime.Instant import kotlin.contracts.InvocationKind import kotlin.contracts.contract +import kotlin.jvm.JvmInline /** * A rate limiter that follows [Discord's rate limits](https://discord.com/developers/docs/topics/rate-limits) for diff --git a/rest/src/main/kotlin/request/HttpUtils.kt b/rest/src/commonMain/kotlin/request/HttpUtils.kt similarity index 98% rename from rest/src/main/kotlin/request/HttpUtils.kt rename to rest/src/commonMain/kotlin/request/HttpUtils.kt index 0e95ee3d96f9..3169e6fffa1e 100644 --- a/rest/src/main/kotlin/request/HttpUtils.kt +++ b/rest/src/commonMain/kotlin/request/HttpUtils.kt @@ -56,7 +56,7 @@ public fun HttpResponse.logString(body: String): String = "[RESPONSE]:${status.value}:${call.request.method.value}:${call.request.url} body:$body" public suspend fun HttpResponse.errorString(): String { - val message = String(this.readBytes()) + val message = bodyAsText() return logString(message) } diff --git a/rest/src/main/kotlin/request/KtorRequestHandler.kt b/rest/src/commonMain/kotlin/request/KtorRequestHandler.kt similarity index 97% rename from rest/src/main/kotlin/request/KtorRequestHandler.kt rename to rest/src/commonMain/kotlin/request/KtorRequestHandler.kt index 63fa4115936f..3ed22ac5e35f 100644 --- a/rest/src/main/kotlin/request/KtorRequestHandler.kt +++ b/rest/src/commonMain/kotlin/request/KtorRequestHandler.kt @@ -1,10 +1,10 @@ package dev.kord.rest.request +import dev.kord.common.http.HttpEngine import dev.kord.rest.json.response.DiscordErrorResponse import dev.kord.rest.ratelimit.* import dev.kord.rest.route.optional import io.ktor.client.* -import io.ktor.client.engine.cio.* import io.ktor.client.request.* import io.ktor.client.request.forms.* import io.ktor.client.statement.* @@ -37,7 +37,7 @@ public class KtorRequestHandler( private val parser: Json = jsonDefault, override val token: String ) : RequestHandler { - private val logger = KotlinLogging.logger("[R]:[KTOR]:[${requestRateLimiter.javaClass.simpleName}]") + private val logger = KotlinLogging.logger("[R]:[KTOR]:[${requestRateLimiter::class.simpleName}]") override tailrec suspend fun handle(request: Request): R { val response = requestRateLimiter.consume(request) { @@ -108,7 +108,7 @@ public fun KtorRequestHandler( clock: Clock = Clock.System, parser: Json = jsonDefault, ): KtorRequestHandler { - val client = HttpClient(CIO) { + val client = HttpClient(HttpEngine) { expectSuccess = false } return KtorRequestHandler(client, requestRateLimiter, clock, parser, token) diff --git a/rest/src/main/kotlin/request/Request.kt b/rest/src/commonMain/kotlin/request/Request.kt similarity index 100% rename from rest/src/main/kotlin/request/Request.kt rename to rest/src/commonMain/kotlin/request/Request.kt diff --git a/rest/src/main/kotlin/request/RequestBuilder.kt b/rest/src/commonMain/kotlin/request/RequestBuilder.kt similarity index 69% rename from rest/src/main/kotlin/request/RequestBuilder.kt rename to rest/src/commonMain/kotlin/request/RequestBuilder.kt index ce17d61c897e..255bcd4fc611 100644 --- a/rest/src/main/kotlin/request/RequestBuilder.kt +++ b/rest/src/commonMain/kotlin/request/RequestBuilder.kt @@ -5,11 +5,7 @@ import dev.kord.rest.NamedFile import dev.kord.rest.route.Route import io.ktor.client.request.forms.* import io.ktor.http.* -import io.ktor.util.cio.* import kotlinx.serialization.SerializationStrategy -import java.io.InputStream -import java.nio.file.Path -import kotlin.DeprecationLevel.HIDDEN public class RequestBuilder(public val route: Route, keySize: Int = 2) { @@ -52,27 +48,6 @@ public class RequestBuilder(public val route: Route, keySize: Int = 2) { headers.append(key, value) } - /** @suppress */ - @Deprecated( - "Use lazy ChannelProvider instead of InputStream. You should also make sure that the stream/channel is only " + - "opened inside the block of the ChannelProvider because it could otherwise be read multiple times " + - "(which isn't allowed).", - ReplaceWith( - "file(name, ChannelProvider { content.toByteReadChannel() })", - "io.ktor.client.request.forms.ChannelProvider", - "io.ktor.utils.io.jvm.javaio.toByteReadChannel", - ), - level = HIDDEN, - ) - @Suppress("DEPRECATION_ERROR") - public fun file(name: String, input: InputStream) { - files.add(NamedFile(input, name)) - } - - public fun file(path: Path) { - file(path.fileName.toString(), ChannelProvider { path.readChannel() }) - } - public fun file(name: String, contentProvider: ChannelProvider) { files.add(NamedFile(name, contentProvider)) } diff --git a/rest/src/main/kotlin/request/RequestHandler.kt b/rest/src/commonMain/kotlin/request/RequestHandler.kt similarity index 100% rename from rest/src/main/kotlin/request/RequestHandler.kt rename to rest/src/commonMain/kotlin/request/RequestHandler.kt diff --git a/rest/src/main/kotlin/request/RestRequestException.kt b/rest/src/commonMain/kotlin/request/RestRequestException.kt similarity index 100% rename from rest/src/main/kotlin/request/RestRequestException.kt rename to rest/src/commonMain/kotlin/request/RestRequestException.kt diff --git a/rest/src/main/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt b/rest/src/commonMain/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt similarity index 79% rename from rest/src/main/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt rename to rest/src/commonMain/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt index 47b4c0bb382c..66e3704c6921 100644 --- a/rest/src/main/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt +++ b/rest/src/commonMain/kotlin/request/StackTraceRecoveringKtorRequestHandler.kt @@ -29,15 +29,9 @@ public class StackTraceRecoveringKtorRequestHandler(private val delegate: KtorRe } /** A [Throwable] used to save the current stack trace before executing a request. */ -internal class RecoveredStackTrace : Throwable("This is the recovered stack trace:") { +internal class RecoveredStackTrace : Throwable("This is the recovered stack trace:") - fun sanitizeStackTrace() { - // Remove artifacts of stack trace capturing. - // The first stack trace element is the creation of the RecoveredStackTrace: - // at dev.kord.rest.request.StackTraceRecoveringKtorRequestHandler.handle(StackTraceRecoveringKtorRequestHandler.kt:19) - stackTrace = stackTrace.copyOfRange(1, stackTrace.size) - } -} +internal expect fun RecoveredStackTrace.sanitizeStackTrace() /** * Returns a new [RequestHandler] with stack trace recovery enabled. diff --git a/rest/src/main/kotlin/route/CdnUrl.kt b/rest/src/commonMain/kotlin/route/CdnUrl.kt similarity index 100% rename from rest/src/main/kotlin/route/CdnUrl.kt rename to rest/src/commonMain/kotlin/route/CdnUrl.kt diff --git a/rest/src/main/kotlin/route/DiscordCdn.kt b/rest/src/commonMain/kotlin/route/DiscordCdn.kt similarity index 100% rename from rest/src/main/kotlin/route/DiscordCdn.kt rename to rest/src/commonMain/kotlin/route/DiscordCdn.kt diff --git a/rest/src/main/kotlin/route/Position.kt b/rest/src/commonMain/kotlin/route/Position.kt similarity index 100% rename from rest/src/main/kotlin/route/Position.kt rename to rest/src/commonMain/kotlin/route/Position.kt diff --git a/rest/src/main/kotlin/route/Route.kt b/rest/src/commonMain/kotlin/route/Route.kt similarity index 100% rename from rest/src/main/kotlin/route/Route.kt rename to rest/src/commonMain/kotlin/route/Route.kt diff --git a/rest/src/main/kotlin/service/ApplicationService.kt b/rest/src/commonMain/kotlin/service/ApplicationService.kt similarity index 100% rename from rest/src/main/kotlin/service/ApplicationService.kt rename to rest/src/commonMain/kotlin/service/ApplicationService.kt diff --git a/rest/src/main/kotlin/service/AuditLogService.kt b/rest/src/commonMain/kotlin/service/AuditLogService.kt similarity index 100% rename from rest/src/main/kotlin/service/AuditLogService.kt rename to rest/src/commonMain/kotlin/service/AuditLogService.kt diff --git a/rest/src/main/kotlin/service/AutoModerationService.kt b/rest/src/commonMain/kotlin/service/AutoModerationService.kt similarity index 100% rename from rest/src/main/kotlin/service/AutoModerationService.kt rename to rest/src/commonMain/kotlin/service/AutoModerationService.kt diff --git a/rest/src/main/kotlin/service/ChannelService.kt b/rest/src/commonMain/kotlin/service/ChannelService.kt similarity index 100% rename from rest/src/main/kotlin/service/ChannelService.kt rename to rest/src/commonMain/kotlin/service/ChannelService.kt diff --git a/rest/src/main/kotlin/service/EmojiService.kt b/rest/src/commonMain/kotlin/service/EmojiService.kt similarity index 100% rename from rest/src/main/kotlin/service/EmojiService.kt rename to rest/src/commonMain/kotlin/service/EmojiService.kt diff --git a/rest/src/main/kotlin/service/GuildService.kt b/rest/src/commonMain/kotlin/service/GuildService.kt similarity index 100% rename from rest/src/main/kotlin/service/GuildService.kt rename to rest/src/commonMain/kotlin/service/GuildService.kt diff --git a/rest/src/main/kotlin/service/InteractionService.kt b/rest/src/commonMain/kotlin/service/InteractionService.kt similarity index 100% rename from rest/src/main/kotlin/service/InteractionService.kt rename to rest/src/commonMain/kotlin/service/InteractionService.kt diff --git a/rest/src/main/kotlin/service/InviteService.kt b/rest/src/commonMain/kotlin/service/InviteService.kt similarity index 100% rename from rest/src/main/kotlin/service/InviteService.kt rename to rest/src/commonMain/kotlin/service/InviteService.kt diff --git a/rest/src/main/kotlin/service/RestClient.kt b/rest/src/commonMain/kotlin/service/RestClient.kt similarity index 100% rename from rest/src/main/kotlin/service/RestClient.kt rename to rest/src/commonMain/kotlin/service/RestClient.kt diff --git a/rest/src/main/kotlin/service/RestService.kt b/rest/src/commonMain/kotlin/service/RestService.kt similarity index 100% rename from rest/src/main/kotlin/service/RestService.kt rename to rest/src/commonMain/kotlin/service/RestService.kt diff --git a/rest/src/main/kotlin/service/StageInstanceService.kt b/rest/src/commonMain/kotlin/service/StageInstanceService.kt similarity index 100% rename from rest/src/main/kotlin/service/StageInstanceService.kt rename to rest/src/commonMain/kotlin/service/StageInstanceService.kt diff --git a/rest/src/main/kotlin/service/StickerService.kt b/rest/src/commonMain/kotlin/service/StickerService.kt similarity index 100% rename from rest/src/main/kotlin/service/StickerService.kt rename to rest/src/commonMain/kotlin/service/StickerService.kt diff --git a/rest/src/main/kotlin/service/TemplateService.kt b/rest/src/commonMain/kotlin/service/TemplateService.kt similarity index 100% rename from rest/src/main/kotlin/service/TemplateService.kt rename to rest/src/commonMain/kotlin/service/TemplateService.kt diff --git a/rest/src/main/kotlin/service/UserService.kt b/rest/src/commonMain/kotlin/service/UserService.kt similarity index 100% rename from rest/src/main/kotlin/service/UserService.kt rename to rest/src/commonMain/kotlin/service/UserService.kt diff --git a/rest/src/main/kotlin/service/VoiceService.kt b/rest/src/commonMain/kotlin/service/VoiceService.kt similarity index 100% rename from rest/src/main/kotlin/service/VoiceService.kt rename to rest/src/commonMain/kotlin/service/VoiceService.kt diff --git a/rest/src/main/kotlin/service/WebhookService.kt b/rest/src/commonMain/kotlin/service/WebhookService.kt similarity index 100% rename from rest/src/main/kotlin/service/WebhookService.kt rename to rest/src/commonMain/kotlin/service/WebhookService.kt diff --git a/rest/src/test/kotlin/Utils.kt b/rest/src/commonTest/kotlin/Utils.kt similarity index 100% rename from rest/src/test/kotlin/Utils.kt rename to rest/src/commonTest/kotlin/Utils.kt diff --git a/rest/src/test/kotlin/builder/CategoryModifyBuilderTest.kt b/rest/src/commonTest/kotlin/builder/CategoryModifyBuilderTest.kt similarity index 61% rename from rest/src/test/kotlin/builder/CategoryModifyBuilderTest.kt rename to rest/src/commonTest/kotlin/builder/CategoryModifyBuilderTest.kt index 5362f8a814bf..7a2efe73d386 100644 --- a/rest/src/test/kotlin/builder/CategoryModifyBuilderTest.kt +++ b/rest/src/commonTest/kotlin/builder/CategoryModifyBuilderTest.kt @@ -1,20 +1,21 @@ package dev.kord.rest.builder -import dev.kord.common.entity.Overwrite import dev.kord.common.entity.optional.Optional import dev.kord.rest.builder.channel.CategoryModifyBuilder -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals class CategoryModifyBuilderTest { @Test + @JsName("test1") fun `builder does not create empty overwrites by default`() { val builder = CategoryModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.permissionOverwrites) + assertEquals(Optional.Missing(), request.permissionOverwrites) } -} \ No newline at end of file +} diff --git a/rest/src/test/kotlin/builder/EditGuildChannelBuilderTest.kt b/rest/src/commonTest/kotlin/builder/EditGuildChannelBuilderTest.kt similarity index 57% rename from rest/src/test/kotlin/builder/EditGuildChannelBuilderTest.kt rename to rest/src/commonTest/kotlin/builder/EditGuildChannelBuilderTest.kt index 8164160e7245..bbce3de7fd79 100644 --- a/rest/src/test/kotlin/builder/EditGuildChannelBuilderTest.kt +++ b/rest/src/commonTest/kotlin/builder/EditGuildChannelBuilderTest.kt @@ -1,44 +1,41 @@ package dev.kord.rest.builder -import dev.kord.common.entity.Overwrite import dev.kord.common.entity.optional.Optional import dev.kord.rest.builder.channel.NewsChannelModifyBuilder import dev.kord.rest.builder.channel.TextChannelModifyBuilder import dev.kord.rest.builder.channel.VoiceChannelModifyBuilder -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals class EditGuildChannelBuilderTest { - /* - 2020-11-16 Kotlin 1.4.20 - You might think these explicit generic types to be unneeded, but the kotlin compiler - won't be able to generate valid bytecode without them. Remove with care. - */ - @Test + @JsName("test1") fun `text builder does not create empty overwrites by default`() { val builder = TextChannelModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.permissionOverwrites) + assertEquals(Optional.Missing(), request.permissionOverwrites) } @Test + @JsName("test2") fun `voice builder does not create empty overwrites by default`() { val builder = VoiceChannelModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.permissionOverwrites) + assertEquals(Optional.Missing(), request.permissionOverwrites) } @Test + @JsName("test3") fun `news builder does not create empty overwrites by default`() { val builder = NewsChannelModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.permissionOverwrites) + assertEquals(Optional.Missing(), request.permissionOverwrites) } } diff --git a/rest/src/test/kotlin/builder/EmojiModifyBuilderTest.kt b/rest/src/commonTest/kotlin/builder/EmojiModifyBuilderTest.kt similarity index 59% rename from rest/src/test/kotlin/builder/EmojiModifyBuilderTest.kt rename to rest/src/commonTest/kotlin/builder/EmojiModifyBuilderTest.kt index 416010494d8b..e413f431e044 100644 --- a/rest/src/test/kotlin/builder/EmojiModifyBuilderTest.kt +++ b/rest/src/commonTest/kotlin/builder/EmojiModifyBuilderTest.kt @@ -1,18 +1,21 @@ -import dev.kord.common.entity.Snowflake +package dev.kord.rest.builder + import dev.kord.common.entity.optional.Optional import dev.kord.rest.builder.guild.EmojiModifyBuilder -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals class EmojiModifyBuilderTest { @Test + @JsName("test1") fun `builder does not create empty roles by default`() { val builder = EmojiModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.roles) + assertEquals(Optional.Missing(), request.roles) } -} \ No newline at end of file +} diff --git a/rest/src/test/kotlin/builder/MemberModifyBuilderTest.kt b/rest/src/commonTest/kotlin/builder/MemberModifyBuilderTest.kt similarity index 62% rename from rest/src/test/kotlin/builder/MemberModifyBuilderTest.kt rename to rest/src/commonTest/kotlin/builder/MemberModifyBuilderTest.kt index 204fba534d53..966f7c1a9826 100644 --- a/rest/src/test/kotlin/builder/MemberModifyBuilderTest.kt +++ b/rest/src/commonTest/kotlin/builder/MemberModifyBuilderTest.kt @@ -1,20 +1,21 @@ package dev.kord.rest.builder -import dev.kord.common.entity.Snowflake import dev.kord.common.entity.optional.Optional import dev.kord.rest.builder.member.MemberModifyBuilder -import org.junit.jupiter.api.Assertions -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals class MemberModifyBuilderTest { @Test + @JsName("test1") fun `builder does not create empty roles by default`() { val builder = MemberModifyBuilder() val request = builder.toRequest() - Assertions.assertEquals(Optional.Missing>(), request.roles) + assertEquals(Optional.Missing(), request.roles) } -} \ No newline at end of file +} diff --git a/rest/src/test/kotlin/builder/guild/GuildModifyBuilderTest.kt b/rest/src/commonTest/kotlin/builder/guild/GuildModifyBuilderTest.kt similarity index 61% rename from rest/src/test/kotlin/builder/guild/GuildModifyBuilderTest.kt rename to rest/src/commonTest/kotlin/builder/guild/GuildModifyBuilderTest.kt index 0762bd31f443..9404eaf5746a 100644 --- a/rest/src/test/kotlin/builder/guild/GuildModifyBuilderTest.kt +++ b/rest/src/commonTest/kotlin/builder/guild/GuildModifyBuilderTest.kt @@ -1,16 +1,18 @@ package dev.kord.rest.builder.guild +import dev.kord.common.Locale import dev.kord.common.entity.optional.Optional -import org.junit.jupiter.api.Assertions.* -import org.junit.jupiter.api.Test -import java.util.* +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals internal class GuildModifyBuilderTest { @Test + @JsName("test1") fun `builder omits non -region and -language`() { val builder = GuildModifyBuilder() - builder.preferredLocale = Locale.Builder().setLanguage("en").setRegion("gb").addUnicodeLocaleAttribute("short").build() + builder.preferredLocale = Locale.ENGLISH_GREAT_BRITAIN val request = builder.toRequest() assertEquals(Optional.Value("en-GB"), request.preferredLocale) diff --git a/rest/src/test/kotlin/json/AuditLogResponseTest.kt b/rest/src/commonTest/kotlin/json/AuditLogResponseTest.kt similarity index 63% rename from rest/src/test/kotlin/json/AuditLogResponseTest.kt rename to rest/src/commonTest/kotlin/json/AuditLogResponseTest.kt index 7671c9cde793..f0d5d2d84bc4 100644 --- a/rest/src/test/kotlin/json/AuditLogResponseTest.kt +++ b/rest/src/commonTest/kotlin/json/AuditLogResponseTest.kt @@ -1,19 +1,23 @@ package dev.kord.rest.json import dev.kord.common.entity.DiscordAuditLog +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test object AuditLogResponseTest { @Test - fun `AuditLogResponseSerialization serialization`() { + @JsName("test1") + fun `AuditLogResponseSerialization serialization`() = runTest { val json = file("auditlog") + @Suppress("UNUSED_VARIABLE") val log = Json.decodeFromString(DiscordAuditLog.serializer(), json) } -} \ No newline at end of file +} diff --git a/rest/src/test/kotlin/json/ErrorTest.kt b/rest/src/commonTest/kotlin/json/ErrorTest.kt similarity index 78% rename from rest/src/test/kotlin/json/ErrorTest.kt rename to rest/src/commonTest/kotlin/json/ErrorTest.kt index acc30485b098..7b641c3b2180 100644 --- a/rest/src/test/kotlin/json/ErrorTest.kt +++ b/rest/src/commonTest/kotlin/json/ErrorTest.kt @@ -1,8 +1,10 @@ package dev.kord.rest.json import dev.kord.rest.json.response.DiscordErrorResponse +import kotlinx.coroutines.test.runTest import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test +import kotlin.js.JsName +import kotlin.test.Test import kotlin.test.assertEquals class ErrorTest { @@ -14,7 +16,8 @@ class ErrorTest { } @Test - fun `correctly serialize error`() { + @JsName("test1") + fun `correctly serialize error`() = runTest { val content = file("error") val parsed = parser.decodeFromString(DiscordErrorResponse.serializer(), content) assertEquals(40001, parsed.code.code) diff --git a/rest/src/commonTest/kotlin/json/Util.kt b/rest/src/commonTest/kotlin/json/Util.kt new file mode 100644 index 000000000000..dd6f1420ef56 --- /dev/null +++ b/rest/src/commonTest/kotlin/json/Util.kt @@ -0,0 +1,8 @@ +package dev.kord.rest.json + +import io.ktor.utils.io.* +import dev.kord.test.file as platformFile +import dev.kord.test.readFile as platformReadFile + +internal suspend fun file(name: String): String = platformFile("rest", "json/$name.json") +internal suspend fun readFile(name: String): ByteReadChannel = platformReadFile("rest", name) diff --git a/rest/src/test/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt b/rest/src/commonTest/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt similarity index 97% rename from rest/src/test/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt rename to rest/src/commonTest/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt index 38a2a8902624..fcd328213564 100644 --- a/rest/src/test/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt +++ b/rest/src/commonTest/kotlin/ratelimit/AbstractRequestRateLimiterTest.kt @@ -10,6 +10,7 @@ import kotlinx.coroutines.withTimeout import kotlinx.coroutines.withTimeoutOrNull import kotlinx.datetime.Clock import kotlinx.datetime.Instant +import kotlin.js.JsName import kotlin.test.Test import kotlin.test.assertEquals import kotlin.time.Duration.Companion.seconds @@ -85,6 +86,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test1") fun `concurrent requests on the same route are handled sequentially`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) @@ -102,6 +104,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test2") fun `a RequestRateLimiter will suspend for rate limited requests with the same identifier`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) @@ -113,6 +116,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test3") fun `a RequestRateLimiter will suspend for rate limited requests with the same bucket`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) @@ -125,6 +129,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test4") fun `a RequestRateLimiter will not suspend for rate limited requests that don't share an identifier`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) @@ -137,6 +142,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test5") fun `an exception during the handling won't lock the handler`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) @@ -163,6 +169,7 @@ abstract class AbstractRequestRateLimiterTest { } @Test + @JsName("test6") fun `REGRESSION a RequestRateLimiter encountering a non 429 error response will not throw`() = runTest { val clock = TestClock(instant, this) val rateLimiter = newRequestRateLimiter(clock) diff --git a/rest/src/test/kotlin/ratelimit/ExclusionRequestRateLimiterTest.kt b/rest/src/commonTest/kotlin/ratelimit/ExclusionRequestRateLimiterTest.kt similarity index 100% rename from rest/src/test/kotlin/ratelimit/ExclusionRequestRateLimiterTest.kt rename to rest/src/commonTest/kotlin/ratelimit/ExclusionRequestRateLimiterTest.kt diff --git a/rest/src/test/kotlin/ratelimit/ParallelRequestRateLimiterTest.kt b/rest/src/commonTest/kotlin/ratelimit/ParallelRequestRateLimiterTest.kt similarity index 100% rename from rest/src/test/kotlin/ratelimit/ParallelRequestRateLimiterTest.kt rename to rest/src/commonTest/kotlin/ratelimit/ParallelRequestRateLimiterTest.kt diff --git a/rest/src/test/kotlin/ratelimit/TestClock.kt b/rest/src/commonTest/kotlin/ratelimit/TestClock.kt similarity index 100% rename from rest/src/test/kotlin/ratelimit/TestClock.kt rename to rest/src/commonTest/kotlin/ratelimit/TestClock.kt diff --git a/rest/src/test/kotlin/request/MessageRequests.kt b/rest/src/commonTest/kotlin/request/MessageRequests.kt similarity index 71% rename from rest/src/test/kotlin/request/MessageRequests.kt rename to rest/src/commonTest/kotlin/request/MessageRequests.kt index 29ae89a92145..e19821c23541 100644 --- a/rest/src/test/kotlin/request/MessageRequests.kt +++ b/rest/src/commonTest/kotlin/request/MessageRequests.kt @@ -5,17 +5,21 @@ import dev.kord.common.entity.DiscordMessage import dev.kord.common.entity.DiscordUser import dev.kord.common.entity.MessageType.Default import dev.kord.common.entity.Snowflake +import dev.kord.rest.json.readFile import dev.kord.rest.service.ChannelService +import dev.kord.test.Platform import io.ktor.client.* import io.ktor.client.engine.mock.* import io.ktor.client.request.forms.* -import io.ktor.util.cio.* -import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.test.runTest import kotlinx.datetime.Clock import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json -import org.junit.jupiter.api.Test -import kotlin.io.path.toPath +import kotlin.js.JsName +import kotlin.test.Test +import kotlin.test.assertEquals +import kotlin.test.assertFalse +import kotlin.test.assertTrue private val mockId = Snowflake(42) private const val fileName = "linus.png" @@ -46,7 +50,8 @@ private val mockMessage = DiscordMessage( class MessageRequests { @Test - fun `attachment channel is read and closed lazily`() = runBlocking { + @JsName("test1") + fun `attachment channel is read and closed lazily`() = runTest { val mockEngine = MockEngine { request -> request.body.toByteArray() // `toByteArray()` reads `fileChannel` @@ -56,21 +61,21 @@ class MessageRequests { val channelService = ChannelService(KtorRequestHandler(client = HttpClient(mockEngine), token = "")) - val fileChannel = ClassLoader.getSystemResource("images/kord.png").toURI().toPath().readChannel() + val fileChannel = readFile("images/kord.png") with(fileChannel) { - assert(!isClosedForWrite) - assert(!isClosedForRead) - assert(totalBytesRead == 0L) + if (Platform.IS_JVM) assertFalse(isClosedForWrite) // only read lazily on jvm + assertFalse(isClosedForRead) + assertEquals(0L, totalBytesRead) val createdMessage = channelService.createMessage(mockId) { addFile(fileName, ChannelProvider { fileChannel }) } - assert(createdMessage == mockMessage) + assertEquals(mockMessage, createdMessage) - assert(isClosedForWrite) - assert(isClosedForRead) - assert(totalBytesRead > 0L) + assertTrue(isClosedForWrite) + assertTrue(isClosedForRead) + assertTrue(totalBytesRead > 0L) } } } diff --git a/rest/src/test/kotlin/request/StackTraceRecoveryTest.kt b/rest/src/commonTest/kotlin/request/StackTraceRecoveryTest.kt similarity index 65% rename from rest/src/test/kotlin/request/StackTraceRecoveryTest.kt rename to rest/src/commonTest/kotlin/request/StackTraceRecoveryTest.kt index 97588c20786b..69aa3eadcd2b 100644 --- a/rest/src/test/kotlin/request/StackTraceRecoveryTest.kt +++ b/rest/src/commonTest/kotlin/request/StackTraceRecoveryTest.kt @@ -8,12 +8,17 @@ import io.ktor.http.* import io.ktor.util.* import io.ktor.utils.io.* import kotlinx.coroutines.test.runTest +import kotlin.js.JsName import kotlin.test.Test -import kotlin.test.assertEquals + +expect class StackTraceElement +expect fun currentThreadStackTrace(): StackTraceElement +internal expect fun RecoveredStackTrace.validate(expected: StackTraceElement) class StackTraceRecoveryTest { @Test + @JsName("test1") fun `test stack trace recovery`() = runTest { val mockEngine = MockEngine { respond( @@ -34,22 +39,15 @@ class StackTraceRecoveryTest { null ) - val stackTrace = Thread.currentThread().stackTrace[1] // [0]: java.lang.Thread.getStackTrace(Thread.java) + val stackTrace = currentThreadStackTrace() try { handler.handle(request) } catch (e: Throwable) { e.printStackTrace() - val recovered = e.suppressedExceptions.first { it is RecoveredStackTrace } + val recovered = e.suppressedExceptions.first { it is RecoveredStackTrace } as RecoveredStackTrace recovered.printStackTrace() - - // at dev.kord.rest.request.StackTraceRecoveryTest$test stack trace recovery$1.invokeSuspend(StackTraceRecoveryTest.kt:39) - with(recovered.stackTrace.first()) { - assertEquals(stackTrace.className, className) - assertEquals(stackTrace.fileName, fileName) - assertEquals(stackTrace.lineNumber + 2, lineNumber) // +2 because capture is two lines deeper - assertEquals(stackTrace.methodName, methodName) - } + recovered.validate(stackTrace) } } } diff --git a/rest/src/test/resources/images/gitlab.png b/rest/src/commonTest/resources/images/gitlab.png similarity index 100% rename from rest/src/test/resources/images/gitlab.png rename to rest/src/commonTest/resources/images/gitlab.png diff --git a/rest/src/test/resources/images/kord.png b/rest/src/commonTest/resources/images/kord.png similarity index 100% rename from rest/src/test/resources/images/kord.png rename to rest/src/commonTest/resources/images/kord.png diff --git a/rest/src/test/resources/json/auditlog.json b/rest/src/commonTest/resources/json/auditlog.json similarity index 100% rename from rest/src/test/resources/json/auditlog.json rename to rest/src/commonTest/resources/json/auditlog.json diff --git a/rest/src/test/resources/json/error.json b/rest/src/commonTest/resources/json/error.json similarity index 100% rename from rest/src/test/resources/json/error.json rename to rest/src/commonTest/resources/json/error.json diff --git a/rest/src/test/resources/simplelogger.properties b/rest/src/commonTest/resources/simplelogger.properties similarity index 100% rename from rest/src/test/resources/simplelogger.properties rename to rest/src/commonTest/resources/simplelogger.properties diff --git a/rest/src/jsMain/kotlin/RecoveredStackTrace.kt b/rest/src/jsMain/kotlin/RecoveredStackTrace.kt new file mode 100644 index 000000000000..0eb06fa964bc --- /dev/null +++ b/rest/src/jsMain/kotlin/RecoveredStackTrace.kt @@ -0,0 +1,17 @@ +package dev.kord.rest.request + +internal actual fun RecoveredStackTrace.sanitizeStackTrace() { + // Remove artifacts of stack trace capturing + // ContextException: + // REMOVE: at 0.doResume_0(/home/mik/IdeaProjects/ktor-suspend-function-gun-tests/src/commonMain/kotlin/Request.kt:12) + // REMOVE: at .doCatching(/home/mik/IdeaProjects/ktor-suspend-function-gun-tests/src/commonMain/kotlin/Request.kt:11) + // at _no_name_provided__304.doResume_0(/home/mik/IdeaProjects/ktor-suspend-function-gun-tests/src/commonTest/kotlin/Test.kt:10) + // at _no_name_provided__304.invoke_29q9u6(/home/mik/IdeaProjects/ktor-suspend-function-gun-tests/src/commonTest/kotlin/Test.kt:9) + val dynamic = asDynamic() + val stack = dynamic.stack as String? ?: "" + dynamic.stack = stack.lines().toMutableList().apply { + repeat(2) { + removeAt(1) + } + }.joinToString("\n") +} diff --git a/rest/src/jsTest/kotlin/dev/kord/rest/request/StackTrace.kt b/rest/src/jsTest/kotlin/dev/kord/rest/request/StackTrace.kt new file mode 100644 index 000000000000..6f23c0ec465e --- /dev/null +++ b/rest/src/jsTest/kotlin/dev/kord/rest/request/StackTrace.kt @@ -0,0 +1,17 @@ +package dev.kord.rest.request + +import kotlin.test.assertEquals + +actual typealias StackTraceElement = String + +//[0]: at $handleCOROUTINE$6.doResume_5yljmg_k$ (C:\Users\micha\IdeaProjects\kord\rest\src\commonMain\kotlin\request\KtorRequestHandler.kt:64:28) +//[1]: at currentThreadStackTrace (C:\Users\micha\IdeaProjects\kord\rest\src\jsTest\kotlin\dev\kord\rest\request\StackTrace.kt:5:59) +//[2]: at $executeCOROUTINE$0.CoroutineImpl.resumeWith_7onugl_k$ (C:\Users\micha\IdeaProjects\kord\rest\build\compileSync\js\test\testDevelopmentExecutable\kotlin\commonMainSources\libraries\stdlib\src\kotlin\util\Standard.kt:55:40) +actual fun currentThreadStackTrace(): StackTraceElement = + Exception().stackTraceToString().lineSequence().drop(3).first().trim() + +internal actual fun RecoveredStackTrace.validate(expected: StackTraceElement) { + // The first two lines are artifacts from coroutines which are not present in expected + val actual = stackTraceToString().lineSequence().drop(2).first().trim() + assertEquals(expected, actual) +} diff --git a/rest/src/jvmMain/kotlin/builder/message/create/MessageCreateBuilderJvm.kt b/rest/src/jvmMain/kotlin/builder/message/create/MessageCreateBuilderJvm.kt new file mode 100644 index 000000000000..4ac22022c303 --- /dev/null +++ b/rest/src/jvmMain/kotlin/builder/message/create/MessageCreateBuilderJvm.kt @@ -0,0 +1,12 @@ +package dev.kord.rest.builder.message.create + +import dev.kord.rest.NamedFile +import io.ktor.client.request.forms.* +import io.ktor.util.cio.* +import java.nio.file.Path + +/** + * Adds a file with the given [path] to the attachments. + */ +public fun MessageCreateBuilder.addFile(path: Path): NamedFile = + addFile(path.fileName.toString(), ChannelProvider { path.readChannel() }) diff --git a/rest/src/jvmMain/kotlin/builder/message/modify/MessageModifyBuilderJvm.kt b/rest/src/jvmMain/kotlin/builder/message/modify/MessageModifyBuilderJvm.kt new file mode 100644 index 000000000000..ea279a114317 --- /dev/null +++ b/rest/src/jvmMain/kotlin/builder/message/modify/MessageModifyBuilderJvm.kt @@ -0,0 +1,12 @@ +package dev.kord.rest.builder.message.modify + +import dev.kord.rest.NamedFile +import io.ktor.client.request.forms.* +import io.ktor.util.cio.* +import java.nio.file.Path + +/** + * Adds a file with the given [path] to the attachments. + */ +public fun MessageModifyBuilder.addFile(path: Path): NamedFile = + addFile(path.fileName.toString(), ChannelProvider { path.readChannel() }) diff --git a/rest/src/jvmMain/kotlin/request/RecoveredStackTrace.kt b/rest/src/jvmMain/kotlin/request/RecoveredStackTrace.kt new file mode 100644 index 000000000000..dcc5f408d749 --- /dev/null +++ b/rest/src/jvmMain/kotlin/request/RecoveredStackTrace.kt @@ -0,0 +1,8 @@ +package dev.kord.rest.request + +internal actual fun RecoveredStackTrace.sanitizeStackTrace() { + // Remove artifacts of stack trace capturing. + // The first stack trace element is the creation of the RecoveredStackTrace: + // at dev.kord.rest.request.StackTraceRecoveringKtorRequestHandler.handle(StackTraceRecoveringKtorRequestHandler.kt:19) + (this as Throwable).stackTrace = stackTrace.copyOfRange(1, stackTrace.size) +} diff --git a/rest/src/jvmMain/kotlin/request/RequestBuilder.kt b/rest/src/jvmMain/kotlin/request/RequestBuilder.kt new file mode 100644 index 000000000000..ea17ede00177 --- /dev/null +++ b/rest/src/jvmMain/kotlin/request/RequestBuilder.kt @@ -0,0 +1,8 @@ +package dev.kord.rest.request + +import io.ktor.client.request.forms.* +import io.ktor.util.cio.* +import java.nio.file.Path + +public fun RequestBuilder.file(path: Path): Unit = + file(path.fileName.toString(), ChannelProvider { path.readChannel() }) diff --git a/rest/src/jvmTest/kotlin/dev/kord/rest/request/StackTrace.kt b/rest/src/jvmTest/kotlin/dev/kord/rest/request/StackTrace.kt new file mode 100644 index 000000000000..a8e643b80082 --- /dev/null +++ b/rest/src/jvmTest/kotlin/dev/kord/rest/request/StackTrace.kt @@ -0,0 +1,20 @@ +package dev.kord.rest.request + +import kotlin.test.assertEquals + +actual typealias StackTraceElement = java.lang.StackTraceElement + +// [0]: java.lang.Thread.getStackTrace(Thread.java) +@Suppress("NOTHING_TO_INLINE") // inlining produces the actual stacktrace +actual inline fun currentThreadStackTrace(): StackTraceElement = Thread.currentThread().stackTrace[1] + +internal actual fun RecoveredStackTrace.validate(expected: StackTraceElement) { + // at dev.kord.rest.request.StackTraceRecoveryTest$test stack trace recovery$1.invokeSuspend(StackTraceRecoveryTest.kt:39) + with(stackTrace.first()) { + assertEquals(expected.className, className) + assertEquals(expected.fileName, fileName) + // -11 because there is a discrepancy due to coroutines + assertEquals(expected.lineNumber - 11, lineNumber) + assertEquals(expected.methodName, methodName) + } +} diff --git a/rest/src/main/kotlin/NamedFile.kt b/rest/src/main/kotlin/NamedFile.kt deleted file mode 100644 index 981014e48780..000000000000 --- a/rest/src/main/kotlin/NamedFile.kt +++ /dev/null @@ -1,51 +0,0 @@ -package dev.kord.rest - -import io.ktor.client.request.forms.* -import io.ktor.utils.io.jvm.javaio.* -import java.io.InputStream -import kotlin.DeprecationLevel.HIDDEN - -public class NamedFile(public val name: String, public val contentProvider: ChannelProvider) { - /** @suppress */ - @Deprecated( - "Use lazy ChannelProvider instead of InputStream. You should also make sure that the stream/channel is only " + - "opened inside the block of the ChannelProvider because it could otherwise be read multiple times " + - "(which isn't allowed).", - ReplaceWith( - "NamedFile(name, ChannelProvider { inputStream.toByteReadChannel() })", - "io.ktor.client.request.forms.ChannelProvider", - "io.ktor.utils.io.jvm.javaio.toByteReadChannel", - ), - level = HIDDEN, - ) - public constructor(name: String, inputStream: InputStream) : this(inputStream, name) - - // TODO remove when above constructor is removed - internal constructor(inputStream: InputStream, name: String) : this( - name, - ChannelProvider { inputStream.toByteReadChannel() }, - ) - - public val url: String get() = "attachment://$name" - - /** @suppress */ - @Deprecated( - "Use ChannelProvider instead of InputStream", - ReplaceWith( - "contentProvider.block().toInputStream()", - "io.ktor.utils.io.jvm.javaio.toInputStream", - ), - level = HIDDEN, - ) - public val inputStream: InputStream get() = _inputStream - private val _inputStream get() = contentProvider.block().toInputStream() // TODO remove with `inputStream` - - public operator fun component1(): String = name - public operator fun component2(): ChannelProvider = contentProvider - public operator fun component3(): String = url - - @Deprecated("Binary compatibility", level = DeprecationLevel.HIDDEN) - @JvmName("component2") - @Suppress("DEPRECATION_ERROR", "FunctionName") - public fun _component2(): InputStream = _inputStream -} diff --git a/rest/src/test/kotlin/json/Util.kt b/rest/src/test/kotlin/json/Util.kt deleted file mode 100644 index a9008a310a30..000000000000 --- a/rest/src/test/kotlin/json/Util.kt +++ /dev/null @@ -1,6 +0,0 @@ -package dev.kord.rest.json - -internal fun file(name: String): String { - val loader = Unit::class.java.classLoader - return loader.getResource("json/$name.json").readText() -} \ No newline at end of file diff --git a/samples/build.gradle.kts b/samples/build.gradle.kts new file mode 100644 index 000000000000..2e16a83d74de --- /dev/null +++ b/samples/build.gradle.kts @@ -0,0 +1,22 @@ +plugins { + `kord-internal-multiplatform-module` +} + +kotlin { + js { + binaries.executable() + } + + sourceSets { + commonMain { + dependencies { + implementation(projects.core) + } + } + jvmMain { + dependencies { + runtimeOnly(libs.slf4j.simple) + } + } + } +} diff --git a/core/src/samples/kotlin/PingBot.kt b/samples/src/commonMain/kotlin/core/PingBot.kt similarity index 91% rename from core/src/samples/kotlin/PingBot.kt rename to samples/src/commonMain/kotlin/core/PingBot.kt index 8569d9e8b4aa..84454f9b636a 100644 --- a/core/src/samples/kotlin/PingBot.kt +++ b/samples/src/commonMain/kotlin/core/PingBot.kt @@ -1,6 +1,6 @@ -import dev.kord.core.Kord +package dev.kord.core + import dev.kord.core.event.message.MessageCreateEvent -import dev.kord.core.on import dev.kord.gateway.Intent import dev.kord.gateway.PrivilegedIntent diff --git a/gateway/src/samples/kotlin/EventListener.kt b/samples/src/commonMain/kotlin/gateway/GatewayExample.kt similarity index 88% rename from gateway/src/samples/kotlin/EventListener.kt rename to samples/src/commonMain/kotlin/gateway/GatewayExample.kt index 1e6e92d062f7..3d323ab72b7c 100644 --- a/gateway/src/samples/kotlin/EventListener.kt +++ b/samples/src/commonMain/kotlin/gateway/GatewayExample.kt @@ -1,9 +1,9 @@ +package dev.kord.gateway + import dev.kord.common.entity.PresenceStatus import dev.kord.common.ratelimit.IntervalRateLimiter -import dev.kord.gateway.* import dev.kord.gateway.retry.LinearRetry import io.ktor.client.* -import io.ktor.client.engine.cio.* import io.ktor.client.plugins.contentnegotiation.* import io.ktor.client.plugins.websocket.* import io.ktor.serialization.kotlinx.json.* @@ -11,18 +11,13 @@ import kotlinx.coroutines.flow.filterIsInstance import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlin.time.Duration.Companion.seconds +import kotlin.time.ExperimentalTime +@OptIn(ExperimentalTime::class) suspend fun main(args: Array) { val token = args.firstOrNull() ?: error("expected a token") val gateway = DefaultGateway { - client = HttpClient(CIO) { - install(WebSockets) - install(ContentNegotiation) { - json() - } - } - reconnectRetry = LinearRetry(2.seconds, 20.seconds, 10) sendRateLimiter = IntervalRateLimiter(limit = 120, interval = 60.seconds) } @@ -39,6 +34,7 @@ suspend fun main(args: Array) { playing("Kord") } } + "!ping" -> gateway.editPresence { status = PresenceStatus.Online afk = false diff --git a/rest/src/samples/kotlin/RestExample.kt b/samples/src/commonMain/kotlin/rest/RestExample.kt similarity index 100% rename from rest/src/samples/kotlin/RestExample.kt rename to samples/src/commonMain/kotlin/rest/RestExample.kt diff --git a/settings.gradle.kts b/settings.gradle.kts index 4a02889a492c..a355a4dd5486 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -8,10 +8,14 @@ include( "bom", "common", "core", + "core:live-tests", + "core-voice", "gateway", "ksp-annotations", "ksp-processors", "rest", + "samples", + "test-kit", "voice", ) diff --git a/test-kit/build.gradle.kts b/test-kit/build.gradle.kts new file mode 100644 index 000000000000..93ad034df435 --- /dev/null +++ b/test-kit/build.gradle.kts @@ -0,0 +1,24 @@ +plugins { + `kord-internal-multiplatform-module` +} + +kotlin { + sourceSets { + commonMain { + dependencies { + api(libs.bundles.test.common) + api(libs.ktor.utils) + } + } + jsMain { + dependencies { + api(libs.bundles.test.js) + } + } + jvmMain { + dependencies { + api(libs.bundles.test.jvm) + } + } + } +} diff --git a/test-kit/src/commonMain/kotlin/Annotations.kt b/test-kit/src/commonMain/kotlin/Annotations.kt new file mode 100644 index 000000000000..bcc93e2653d5 --- /dev/null +++ b/test-kit/src/commonMain/kotlin/Annotations.kt @@ -0,0 +1,16 @@ +@file:OptIn(ExperimentalMultiplatform::class) + +package dev.kord.test + +import kotlin.annotation.AnnotationTarget.CLASS +import kotlin.annotation.AnnotationTarget.FUNCTION + +/** Ignores this test on JS platforms. */ +@Target(CLASS, FUNCTION) +@OptionalExpectation +expect annotation class IgnoreOnJs() + +/** Ignores this test on the JVM. */ +@Target(CLASS, FUNCTION) +@OptionalExpectation +expect annotation class IgnoreOnJvm() diff --git a/test-kit/src/commonMain/kotlin/Platform.kt b/test-kit/src/commonMain/kotlin/Platform.kt new file mode 100644 index 000000000000..587c0f0a3413 --- /dev/null +++ b/test-kit/src/commonMain/kotlin/Platform.kt @@ -0,0 +1,13 @@ +package dev.kord.test + +import io.ktor.utils.io.* + +expect object Platform { + val IS_JVM: Boolean + val IS_NODE: Boolean + val IS_BROWSER: Boolean +} + +expect fun getEnv(name: String): String? +expect suspend fun file(project: String, path: String): String +expect suspend fun readFile(project: String, path: String): ByteReadChannel diff --git a/test-kit/src/jsMain/kotlin/IgnoreOnJs.kt b/test-kit/src/jsMain/kotlin/IgnoreOnJs.kt new file mode 100644 index 000000000000..59d75c64b7ed --- /dev/null +++ b/test-kit/src/jsMain/kotlin/IgnoreOnJs.kt @@ -0,0 +1,5 @@ +package dev.kord.test + +import kotlin.test.Ignore + +actual typealias IgnoreOnJs = Ignore diff --git a/test-kit/src/jsMain/kotlin/Platform.kt b/test-kit/src/jsMain/kotlin/Platform.kt new file mode 100644 index 000000000000..70be0397537c --- /dev/null +++ b/test-kit/src/jsMain/kotlin/Platform.kt @@ -0,0 +1,25 @@ +package dev.kord.test + +import io.ktor.utils.io.* +import js.core.get +import node.process.process + +actual object Platform { + actual const val IS_JVM: Boolean = false + actual val IS_NODE: Boolean + get() = js( + "typeof process !== 'undefined' && process.versions != null && process.versions.node != null" + ) as Boolean + actual val IS_BROWSER: Boolean + get() = js( + "typeof window !== 'undefined' && typeof window.document !== 'undefined' || typeof self !== 'undefined' && typeof self.location !== 'undefined'" + ) as Boolean +} + +actual fun getEnv(name: String) = process.env[name] + +actual suspend fun file(project: String, path: String): String = + if (Platform.IS_NODE) nodeFile(project, path) else TODO("Browser JS is not supported yet") + +actual suspend fun readFile(project: String, path: String): ByteReadChannel = + if (Platform.IS_NODE) nodeReadFile(project, path) else TODO("Browser JS is not supported yet") diff --git a/test-kit/src/jsMain/kotlin/Platform.node.kt b/test-kit/src/jsMain/kotlin/Platform.node.kt new file mode 100644 index 000000000000..e0e4426a2add --- /dev/null +++ b/test-kit/src/jsMain/kotlin/Platform.node.kt @@ -0,0 +1,22 @@ +package dev.kord.test + +import io.ktor.utils.io.* +import js.core.get +import js.core.toList +import node.buffer.Buffer +import node.buffer.BufferEncoding +import node.process.process + +internal suspend fun nodeFile(project: String, path: String): String = + node.fs.readFile("${process.env["PROJECT_ROOT"]}/$project/src/commonTest/resources/$path") + .toString(BufferEncoding.utf8) + +internal suspend fun nodeReadFile(project: String, path: String): ByteReadChannel { + val buffer = node.fs.readFile("${process.env["PROJECT_ROOT"]}/$project/src/commonTest/resources/$path") + + return ByteReadChannel(buffer.toByteArray()) +} + +private fun Buffer.toByteArray() = values().toList() + .map(Int::toByte) + .toByteArray() diff --git a/test-kit/src/jvmMain/kotlin/IgnoreOnJvm.kt b/test-kit/src/jvmMain/kotlin/IgnoreOnJvm.kt new file mode 100644 index 000000000000..b324faa889ff --- /dev/null +++ b/test-kit/src/jvmMain/kotlin/IgnoreOnJvm.kt @@ -0,0 +1,5 @@ +package dev.kord.test + +import org.junit.jupiter.api.Disabled + +actual typealias IgnoreOnJvm = Disabled diff --git a/test-kit/src/jvmMain/kotlin/Platform.kt b/test-kit/src/jvmMain/kotlin/Platform.kt new file mode 100644 index 000000000000..363270db8d56 --- /dev/null +++ b/test-kit/src/jvmMain/kotlin/Platform.kt @@ -0,0 +1,15 @@ +package dev.kord.test + +import io.ktor.utils.io.* +import io.ktor.utils.io.jvm.javaio.* + +actual object Platform { + actual const val IS_JVM: Boolean = true + actual const val IS_NODE: Boolean = false + actual const val IS_BROWSER: Boolean = false +} + +actual fun getEnv(name: String): String? = System.getenv(name) +actual suspend fun file(project: String, path: String): String = ClassLoader.getSystemResource(path).readText() +actual suspend fun readFile(project: String, path: String): ByteReadChannel = + ClassLoader.getSystemResourceAsStream(path)!!.toByteReadChannel() diff --git a/voice/build.gradle.kts b/voice/build.gradle.kts index e43848547967..da6b41f43831 100644 --- a/voice/build.gradle.kts +++ b/voice/build.gradle.kts @@ -10,7 +10,6 @@ dependencies { api(projects.gateway) compileOnly(projects.kspAnnotations) - ksp(projects.kspProcessors) api(libs.ktor.network) } diff --git a/voice/src/main/kotlin/gateway/Ticker.kt b/voice/src/main/kotlin/gateway/Ticker.kt index 59d6e292f67a..770e206b2fa0 100644 --- a/voice/src/main/kotlin/gateway/Ticker.kt +++ b/voice/src/main/kotlin/gateway/Ticker.kt @@ -5,7 +5,6 @@ import kotlinx.coroutines.* /** * A reusable fixed rate ticker. */ -@ObsoleteCoroutinesApi internal class Ticker { // we only want one of these private var tickerJob: Job? = null @@ -23,4 +22,4 @@ internal class Ticker { fun stop() { tickerJob?.cancel() } -} \ No newline at end of file +} diff --git a/voice/src/main/kotlin/gateway/handler/HeartbeatHandler.kt b/voice/src/main/kotlin/gateway/handler/HeartbeatHandler.kt index b443e2c26b7a..f41c5ae470ff 100644 --- a/voice/src/main/kotlin/gateway/handler/HeartbeatHandler.kt +++ b/voice/src/main/kotlin/gateway/handler/HeartbeatHandler.kt @@ -2,7 +2,6 @@ package dev.kord.voice.gateway.handler import dev.kord.voice.gateway.* import kotlinx.atomicfu.atomic -import kotlinx.coroutines.ObsoleteCoroutinesApi import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.launch @@ -10,7 +9,6 @@ import kotlin.time.Duration import kotlin.time.TimeMark import kotlin.time.TimeSource -@OptIn(ObsoleteCoroutinesApi::class) internal class HeartbeatHandler( flow: Flow, private val send: suspend (Command) -> Unit,