Skip to content

Commit

Permalink
Decouple test TerminalReader from TestTty (#731)
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeWharton authored Feb 24, 2025
1 parent 0898ab6 commit 7edf0ff
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,9 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.test.runTest

abstract class BaseTerminalParserTest {
internal val testTty = TestTty()
internal val reader = testTty.terminalReader()
private val testTerminalReader = TestTerminalReader()
internal val testTty = testTerminalReader.testTty
internal val reader = testTerminalReader.terminalReader
private val runLoop = GlobalScope.launch(Dispatchers.IO) {
reader.runParseLoop()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.jakewharton.mosaic.terminal

import com.jakewharton.mosaic.terminal.event.Event
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED

internal fun TestTerminalReader(): TestTerminalReader {
val events = Channel<Event>(UNLIMITED)
val platformEventHandler = PlatformEventHandler(events, emitDebugEvents = false)
val testTty = TestTty.create(platformEventHandler)
val reader = TerminalReader(testTty.tty, events, emitDebugEvents = false)
return TestTerminalReader(testTty, reader)
}

internal class TestTerminalReader(
val testTty: TestTty,
val terminalReader: TerminalReader,
)
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package com.jakewharton.mosaic.terminal

internal expect fun TestTty(): TestTty

internal expect class TestTty : AutoCloseable {
val tty: Tty
companion object {
fun create(callback: Tty.Callback): TestTty
}

fun terminalReader(emitDebugEvents: Boolean = false): TerminalReader
val tty: Tty

// TODO Take ByteString once it migrates to stdlib,
// or if Sink/RawSink migrates expose that as a val.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,12 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch

class TtyTest {
private val testTty = TestTty()
private val testTty = TestTty.create(object : Tty.Callback {
override fun onFocus(focused: Boolean) {}
override fun onKey() {}
override fun onMouse() {}
override fun onResize(columns: Int, rows: Int, width: Int, height: Int) {}
})
private val tty = testTty.tty

@AfterTest fun after() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,28 +8,26 @@ import com.jakewharton.mosaic.terminal.event.Event
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED

internal actual fun TestTty(): TestTty {
val events = Channel<Event>(UNLIMITED)
val callbackPtr = ttyCallbackInit(PlatformEventHandler(events, emitDebugEvents = false))
if (callbackPtr != 0L) {
val testTtyPtr = testTtyInit(callbackPtr)
if (testTtyPtr != 0L) {
val ttyPtr = testTtyGetTty(testTtyPtr)
val tty = Tty(ttyPtr, callbackPtr)
return TestTty(testTtyPtr, events, tty)
}
ttyCallbackFree(callbackPtr)
}
throw OutOfMemoryError()
}

internal actual class TestTty(
private var testTtyPtr: Long,
private val events: Channel<Event>,
actual val tty: Tty,
) : AutoCloseable {
actual fun terminalReader(emitDebugEvents: Boolean): TerminalReader {
return TerminalReader(tty, events, emitDebugEvents)
actual companion object {
actual fun create(callback: Tty.Callback): TestTty {
val events = Channel<Event>(UNLIMITED)
val callbackPtr = ttyCallbackInit(PlatformEventHandler(events, emitDebugEvents = false))
if (callbackPtr != 0L) {
val testTtyPtr = testTtyInit(callbackPtr)
if (testTtyPtr != 0L) {
val ttyPtr = testTtyGetTty(testTtyPtr)
val tty = Tty(ttyPtr, callbackPtr)
return TestTty(testTtyPtr, events, tty)
}
ttyCallbackFree(callbackPtr)
}
throw OutOfMemoryError()
}
}

actual fun write(buffer: ByteArray) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,35 +12,33 @@ import kotlinx.cinterop.usePinned
import kotlinx.coroutines.channels.Channel
import kotlinx.coroutines.channels.Channel.Factory.UNLIMITED

internal actual fun TestTty(): TestTty {
val events = Channel<Event>(UNLIMITED)

val callback = PlatformEventHandler(events, emitDebugEvents = false)
val callbackRef = StableRef.create(callback)
val callbackPtr = callbackRef.toNativeAllocationIn(nativeHeap).ptr

val testTtyPtr = testTty_init(callbackPtr).useContents {
testTty?.let { return@useContents it }

nativeHeap.free(callbackPtr)
callbackRef.dispose()

check(error == 0U) { "Unable to create test tty: $error" }
throw OutOfMemoryError()
}

val ttyPtr = testTty_getTty(testTtyPtr)!!
val tty = Tty(ttyPtr, callbackPtr, callbackRef)
return TestTty(testTtyPtr, events, tty)
}

internal actual class TestTty(
private var ptr: CPointer<MosaicTestTty>?,
private val events: Channel<Event>,
actual val tty: Tty,
) : AutoCloseable {
actual fun terminalReader(emitDebugEvents: Boolean): TerminalReader {
return TerminalReader(tty, events, emitDebugEvents)
actual companion object {
actual fun create(callback: Tty.Callback): TestTty {
val events = Channel<Event>(UNLIMITED)

val callback = PlatformEventHandler(events, emitDebugEvents = false)
val callbackRef = StableRef.create(callback)
val callbackPtr = callbackRef.toNativeAllocationIn(nativeHeap).ptr

val testTtyPtr = testTty_init(callbackPtr).useContents {
testTty?.let { return@useContents it }

nativeHeap.free(callbackPtr)
callbackRef.dispose()

check(error == 0U) { "Unable to create test tty: $error" }
throw OutOfMemoryError()
}

val ttyPtr = testTty_getTty(testTtyPtr)!!
val tty = Tty(ttyPtr, callbackPtr, callbackRef)
return TestTty(testTtyPtr, events, tty)
}
}

actual fun write(buffer: ByteArray) {
Expand Down

0 comments on commit 7edf0ff

Please sign in to comment.