From 2fd68d67e35057c29845f5f962c1835ada0e710b Mon Sep 17 00:00:00 2001 From: James Rich <2199651+jamesarich@users.noreply.github.com> Date: Wed, 18 Mar 2026 20:21:56 -0500 Subject: [PATCH] test(network): Add property-based tests for StreamInterface --- .../core/network/radio/StreamInterfaceTest.kt | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 core/network/src/commonTest/kotlin/org/meshtastic/core/network/radio/StreamInterfaceTest.kt diff --git a/core/network/src/commonTest/kotlin/org/meshtastic/core/network/radio/StreamInterfaceTest.kt b/core/network/src/commonTest/kotlin/org/meshtastic/core/network/radio/StreamInterfaceTest.kt new file mode 100644 index 000000000..2bc0b04f2 --- /dev/null +++ b/core/network/src/commonTest/kotlin/org/meshtastic/core/network/radio/StreamInterfaceTest.kt @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2026 Meshtastic LLC + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +package org.meshtastic.core.network.radio + +import dev.mokkery.MockMode +import dev.mokkery.answering.returns +import dev.mokkery.every +import dev.mokkery.mock +import dev.mokkery.verify +import io.kotest.property.Arb +import io.kotest.property.arbitrary.byte +import io.kotest.property.arbitrary.byteArray +import io.kotest.property.arbitrary.int +import io.kotest.property.checkAll +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.meshtastic.core.network.transport.StreamFrameCodec +import org.meshtastic.core.repository.RadioInterfaceService +import kotlin.test.BeforeTest +import kotlin.test.Test +import kotlin.test.assertTrue + +class StreamInterfaceTest { + + private val radioService: RadioInterfaceService = mock(MockMode.autofill) + private lateinit var fakeStream: FakeStreamInterface + + class FakeStreamInterface(service: RadioInterfaceService) : StreamInterface(service) { + val sentBytes = mutableListOf() + override fun sendBytes(p: ByteArray) { sentBytes.add(p) } + override fun flushBytes() { /* no-op */ } + override fun keepAlive() { /* no-op */ } + fun feed(b: Byte) = readChar(b) + public override fun connect() = super.connect() + } + + @BeforeTest + fun setUp() { + every { radioService.serviceScope } returns TestScope() + } + + @Test + fun `handleSendToRadio property test`() = runTest { + fakeStream = FakeStreamInterface(radioService) + + checkAll(Arb.byteArray(Arb.int(0, 512), Arb.byte())) { payload -> + fakeStream.handleSendToRadio(payload) + } + } + + @Test + fun `readChar property test`() = runTest { + fakeStream = FakeStreamInterface(radioService) + + checkAll(Arb.byteArray(Arb.int(0, 100), Arb.byte())) { data -> + data.forEach { fakeStream.feed(it) } + // Ensure no crash + } + } + + @Test + fun `connect sends wake bytes`() { + fakeStream = FakeStreamInterface(radioService) + fakeStream.connect() + + assertTrue(fakeStream.sentBytes.isNotEmpty()) + assertTrue(fakeStream.sentBytes[0].contentEquals(StreamFrameCodec.WAKE_BYTES)) + verify { radioService.onConnect() } + } +}