mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
refactor [lsp]: add tests for the read line func
GitOrigin-RevId: 153cdd1c4f05c31292946809514890384a89ec53
This commit is contained in:
committed by
intellij-monorepo-bot
parent
b212bdd7ac
commit
96728011dc
Generated
+1
@@ -24,6 +24,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/ktor/network/tls/fleet.ktor.network.tls.iml" filepath="$PROJECT_DIR$/fleet/ktor/network/tls/fleet.ktor.network.tls.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/ktor/server/cio/fleet.ktor.server.cio.iml" filepath="$PROJECT_DIR$/fleet/ktor/server/cio/fleet.ktor.server.cio.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/lsp.protocol/fleet.lsp.protocol.iml" filepath="$PROJECT_DIR$/fleet/lsp.protocol/fleet.lsp.protocol.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/lsp.protocol/test/fleet.lsp.protocol.test.iml" filepath="$PROJECT_DIR$/fleet/lsp.protocol/test/fleet.lsp.protocol.test.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/modules/api/fleet.modules.api.iml" filepath="$PROJECT_DIR$/fleet/modules/api/fleet.modules.api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/modules/jvm/fleet.modules.jvm.iml" filepath="$PROJECT_DIR$/fleet/modules/jvm/fleet.modules.jvm.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/fleet/multiplatform.shims/fleet.multiplatform.shims.iml" filepath="$PROJECT_DIR$/fleet/multiplatform.shims/fleet.multiplatform.shims.iml" />
|
||||
|
||||
@@ -240,6 +240,7 @@ fleet/ktor/client/core
|
||||
fleet/ktor/network/tls
|
||||
fleet/ktor/server/cio
|
||||
fleet/lsp.protocol
|
||||
fleet/lsp.protocol/test
|
||||
fleet/modules/api
|
||||
fleet/modules/jvm
|
||||
fleet/multiplatform.shims
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
### auto-generated section `build fleet.lsp.protocol.test` start
|
||||
load("//build:compiler-options.bzl", "create_kotlinc_options")
|
||||
load("@rules_jvm//:jvm.bzl", "jvm_library")
|
||||
|
||||
create_kotlinc_options(
|
||||
name = "custom_test",
|
||||
opt_in = [
|
||||
"kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"kotlinx.serialization.ExperimentalSerializationApi",
|
||||
"kotlin.concurrent.atomics.ExperimentalAtomicApi",
|
||||
],
|
||||
x_consistent_data_class_copy_visibility = True,
|
||||
x_context_parameters = True,
|
||||
x_lambdas = "class"
|
||||
)
|
||||
|
||||
jvm_library(
|
||||
name = "test",
|
||||
visibility = ["//visibility:public"],
|
||||
srcs = glob([], allow_empty = True, exclude = ["**/module-info.java"]),
|
||||
runtime_deps = [
|
||||
"@lib//:kotlin-stdlib",
|
||||
"@lib//:kotlinx-coroutines-core",
|
||||
"@lib//:kotlinx-io-core",
|
||||
]
|
||||
)
|
||||
|
||||
jvm_library(
|
||||
name = "test_test_lib",
|
||||
module_name = "fleet.lsp.protocol.test",
|
||||
visibility = ["//visibility:public"],
|
||||
srcs = glob(["src/**/*.kt", "src/**/*.java", "src/**/*.form"], allow_empty = True, exclude = ["**/module-info.java"]),
|
||||
kotlinc_opts = ":custom_test",
|
||||
deps = [
|
||||
"@lib//:kotlin-stdlib",
|
||||
"@lib//:kotlinx-coroutines-core",
|
||||
"@lib//:kotlinx-io-core",
|
||||
"//fleet/ktor/client/cio",
|
||||
"//fleet/ktor/client/core",
|
||||
"//fleet/ktor/network/tls",
|
||||
"//fleet/lsp.protocol",
|
||||
"//fleet/test-runtime",
|
||||
],
|
||||
runtime_deps = [":test"]
|
||||
)
|
||||
### auto-generated section `build fleet.lsp.protocol.test` end
|
||||
|
||||
### auto-generated section `test fleet.lsp.protocol.test` start
|
||||
load("@community//build:tests-options.bzl", "jps_test")
|
||||
|
||||
jps_test(
|
||||
name = "test_test",
|
||||
runtime_deps = [":test_test_lib"]
|
||||
)
|
||||
### auto-generated section `test fleet.lsp.protocol.test` end
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="FacetManager">
|
||||
<facet type="kotlin-language" name="Kotlin">
|
||||
<configuration version="5" platform="JVM 21" allPlatforms="JVM [21]" useProjectSettings="false">
|
||||
<compilerSettings>
|
||||
<option name="additionalArguments" value="-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi -Xlambdas=class -Xconsistent-data-class-copy-visibility -opt-in=kotlinx.serialization.ExperimentalSerializationApi -Xcontext-parameters -Xjvm-default=all -XXLanguage:+AllowEagerSupertypeAccessibilityChecks -opt-in=kotlin.concurrent.atomics.ExperimentalAtomicApi -progressive" />
|
||||
</compilerSettings>
|
||||
<compilerArguments>
|
||||
<stringArguments>
|
||||
<stringArg name="jvmTarget" arg="21" />
|
||||
<stringArg name="apiVersion" arg="2.3" />
|
||||
<stringArg name="languageVersion" arg="2.3" />
|
||||
</stringArguments>
|
||||
</compilerArguments>
|
||||
</configuration>
|
||||
</facet>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-stdlib" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-coroutines-core" level="project" />
|
||||
<orderEntry type="library" name="kotlinx-io-core" level="project" />
|
||||
<orderEntry type="module" module-name="fleet.ktor.client.cio" scope="TEST" />
|
||||
<orderEntry type="module" module-name="fleet.ktor.client.core" scope="TEST" />
|
||||
<orderEntry type="module" module-name="fleet.ktor.network.tls" scope="TEST" />
|
||||
<orderEntry type="module" module-name="fleet.lsp.protocol" scope="TEST" />
|
||||
<orderEntry type="module" module-name="fleet.test.runtime" scope="TEST" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,72 @@
|
||||
// IMPORT__MARKER_START
|
||||
import fleet.buildtool.conventions.configureAtMostOneJvmTargetOrThrow
|
||||
import fleet.buildtool.conventions.withJavaSourceSet
|
||||
// IMPORT__MARKER_END
|
||||
plugins {
|
||||
alias(libs.plugins.kotlin.multiplatform)
|
||||
id("fleet.project-module-conventions")
|
||||
id("fleet.toolchain-conventions")
|
||||
id("fleet.module-publishing-conventions")
|
||||
id("fleet.sdk-repositories-publishing-conventions")
|
||||
id("fleet.open-source-module-conventions")
|
||||
alias(libs.plugins.dokka)
|
||||
// GRADLE_PLUGINS__MARKER_START
|
||||
id("fleet-module")
|
||||
// GRADLE_PLUGINS__MARKER_END
|
||||
}
|
||||
|
||||
fleetModule {
|
||||
module {
|
||||
name = "fleet.lsp.protocol.test"
|
||||
importedFromJps {}
|
||||
test {}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class)
|
||||
kotlin {
|
||||
// KOTLIN__MARKER_START
|
||||
compilerOptions.freeCompilerArgs = listOf(
|
||||
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
|
||||
"-Xlambdas=class",
|
||||
"-Xconsistent-data-class-copy-visibility",
|
||||
"-opt-in=kotlinx.serialization.ExperimentalSerializationApi",
|
||||
"-Xcontext-parameters",
|
||||
"-Xjvm-default=all",
|
||||
"-XXLanguage:+AllowEagerSupertypeAccessibilityChecks",
|
||||
"-opt-in=kotlin.concurrent.atomics.ExperimentalAtomicApi",
|
||||
"-progressive",
|
||||
)
|
||||
jvm {}
|
||||
sourceSets.jvmTest.configure { kotlin.srcDir(layout.projectDirectory.dir("../src")) }
|
||||
configureAtMostOneJvmTargetOrThrow { compilations.named("test") { withJavaSourceSet { javaSourceSet -> javaSourceSet.java.srcDir(layout.projectDirectory.dir("../src")) } } }
|
||||
sourceSets.commonMain.configure { kotlin.srcDir(layout.projectDirectory.dir("../srcCommonMain")) }
|
||||
sourceSets.commonMain.configure { resources.srcDir(layout.projectDirectory.dir("../resourcesCommonMain")) }
|
||||
sourceSets.commonTest.configure { kotlin.srcDir(layout.projectDirectory.dir("../srcCommonTest")) }
|
||||
sourceSets.commonTest.configure { resources.srcDir(layout.projectDirectory.dir("../resourcesCommonTest")) }
|
||||
sourceSets.jvmMain.configure { kotlin.srcDir(layout.projectDirectory.dir("../srcJvmMain")) }
|
||||
configureAtMostOneJvmTargetOrThrow { compilations.named("main") { withJavaSourceSet { javaSourceSet -> javaSourceSet.java.srcDir(layout.projectDirectory.dir("../srcJvmMain")) } } }
|
||||
sourceSets.jvmMain.configure { resources.srcDir(layout.projectDirectory.dir("../resourcesJvmMain")) }
|
||||
sourceSets.jvmTest.configure { kotlin.srcDir(layout.projectDirectory.dir("../srcJvmTest")) }
|
||||
configureAtMostOneJvmTargetOrThrow { compilations.named("test") { withJavaSourceSet { javaSourceSet -> javaSourceSet.java.srcDir(layout.projectDirectory.dir("../srcJvmTest")) } } }
|
||||
sourceSets.jvmTest.configure { resources.srcDir(layout.projectDirectory.dir("../resourcesJvmTest")) }
|
||||
sourceSets.commonMain.dependencies {
|
||||
implementation(jps.org.jetbrains.kotlin.kotlin.stdlib1993400674.get().let { "${it.group}:${it.name}:${it.version}" }) {
|
||||
exclude(group = "org.jetbrains", module = "annotations")
|
||||
}
|
||||
implementation(jps.org.jetbrains.intellij.deps.kotlinx.kotlinx.coroutines.core.jvm930800474.get().let { "${it.group}:kotlinx-coroutines-core:${it.version}" }) {
|
||||
isTransitive = false
|
||||
}
|
||||
implementation(jps.org.jetbrains.kotlinx.kotlinx.io.core.jvm479158162.get().let { "${it.group}:kotlinx-io-core:${it.version}" }) {
|
||||
exclude(group = "org.jetbrains.kotlin", module = "kotlin-stdlib")
|
||||
}
|
||||
}
|
||||
sourceSets.commonTest.dependencies {
|
||||
implementation(project(":fleet.ktor.client.cio"))
|
||||
implementation(project(":fleet.ktor.client.core"))
|
||||
implementation(project(":fleet.ktor.network.tls"))
|
||||
implementation(project(":fleet.lsp.protocol"))
|
||||
implementation(project(":fleet.test.runtime"))
|
||||
}
|
||||
// KOTLIN__MARKER_END
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package com.jetbrains.lsp.test
|
||||
|
||||
import com.jetbrains.lsp.implementation.ByteReader
|
||||
import com.jetbrains.lsp.implementation.readUTF8Line
|
||||
import io.ktor.utils.io.*
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.flow.flow
|
||||
import kotlinx.coroutines.flow.withIndex
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import kotlinx.io.Source
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
private const val LF = 0x0A.toByte()
|
||||
private const val CR = 0x0D.toByte()
|
||||
|
||||
class ByteReaderTest {
|
||||
|
||||
@Test
|
||||
fun `readUTF8Line reads an LF-terminated line`() {
|
||||
runBlocking {
|
||||
val message = "Hello, world!"
|
||||
val channel = ByteChannel()
|
||||
val reader = ByteChannelReader(channel)
|
||||
|
||||
val line = async { reader.readUTF8Line() }
|
||||
channel.writeLine(message, LF)
|
||||
channel.flushAndClose()
|
||||
|
||||
assertEquals(message, line.await())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `readUTF8Line reads an LF-terminated line sent byte by byte`() {
|
||||
runBlocking {
|
||||
val message = "Hello, world!"
|
||||
val channel = ByteChannel()
|
||||
val reader = ByteChannelReader(channel)
|
||||
|
||||
val line = async { reader.readUTF8Line() }
|
||||
message.toByteArray(Charsets.UTF_8).forEach { byte ->
|
||||
channel.writeByte(byte)
|
||||
channel.flush()
|
||||
}
|
||||
channel.writeByte(LF)
|
||||
channel.flushAndClose()
|
||||
|
||||
assertEquals(message, line.await())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `readUTF8Line reads a CRLF-terminated line sent byte by byte`() {
|
||||
runBlocking {
|
||||
val message = "Hello, world!"
|
||||
val channel = ByteChannel()
|
||||
val reader = ByteChannelReader(channel)
|
||||
|
||||
val line = async { reader.readUTF8Line() }
|
||||
message.toByteArray(Charsets.UTF_8).forEach { byte ->
|
||||
channel.writeByte(byte)
|
||||
channel.flush()
|
||||
}
|
||||
channel.writeBytes(CR, LF)
|
||||
channel.flushAndClose()
|
||||
|
||||
assertEquals(message, line.await())
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `readUTF8Line reads several LF-terminated lines`() {
|
||||
runBlocking {
|
||||
val messages = listOf(
|
||||
"Hello", "world", "how", "are", "you", "doing"
|
||||
)
|
||||
val channel = ByteChannel()
|
||||
val reader = ByteChannelReader(channel)
|
||||
|
||||
val lines = flow {
|
||||
while (!reader.isClosedForRead) {
|
||||
emit(reader.readUTF8Line())
|
||||
}
|
||||
}
|
||||
|
||||
for (message in messages) {
|
||||
channel.writeLine(message, LF)
|
||||
channel.flush()
|
||||
}
|
||||
channel.close()
|
||||
|
||||
lines.withIndex().collect { (i, line) ->
|
||||
assertEquals(messages[i], line)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ByteWriteChannel.writeBytes(vararg bytes: Byte) {
|
||||
for (byte in bytes) {
|
||||
writeByte(byte)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun ByteWriteChannel.writeLine(s: String, vararg terminators: Byte = byteArrayOf(LF)) {
|
||||
writeStringUtf8(s)
|
||||
for (terminator in terminators) {
|
||||
writeByte(terminator)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(InternalAPI::class)
|
||||
internal class ByteChannelReader(val underlying: ByteChannel) : ByteReader {
|
||||
override val closedCause: Throwable?
|
||||
get() = underlying.closedCause
|
||||
override val isClosedForRead: Boolean
|
||||
get() = underlying.isClosedForRead
|
||||
override val readBuffer: Source
|
||||
get() = underlying.readBuffer
|
||||
|
||||
override suspend fun awaitContent(min: Int): Boolean {
|
||||
return underlying.awaitContent()
|
||||
}
|
||||
|
||||
override fun cancel(cause: Throwable?) {
|
||||
underlying.cancel(cause)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user