






















@@ -0,0 +1,55 @@
1+package ai.openclaw.app.voice
2+3+import android.os.Bundle
4+import android.speech.RecognitionListener
5+import android.speech.SpeechRecognizer
6+import kotlinx.coroutines.ExperimentalCoroutinesApi
7+import kotlinx.coroutines.test.advanceUntilIdle
8+import kotlinx.coroutines.test.runTest
9+import org.junit.Assert.assertEquals
10+import org.junit.Test
11+import org.junit.runner.RunWith
12+import org.robolectric.RobolectricTestRunner
13+import org.robolectric.RuntimeEnvironment
14+import org.robolectric.annotation.Config
15+16+@RunWith(RobolectricTestRunner::class)
17+@Config(sdk = [34])
18+class VoiceWakeManagerTest {
19+ @Test
20+ @OptIn(ExperimentalCoroutinesApi::class)
21+fun repeatedCommandDispatchesInNewRecognitionCycle() =
22+ runTest {
23+val commands = mutableListOf<String>()
24+val manager =
25+VoiceWakeManager(
26+ context = RuntimeEnvironment.getApplication(),
27+ scope = this,
28+ onCommand = { command -> commands += command },
29+ )
30+ manager.setTriggerWords(listOf("claude"))
31+val listener = recognitionListener(manager)
32+33+ listener.onReadyForSpeech(null)
34+ listener.onPartialResults(recognitionResults("claude take a photo"))
35+ listener.onResults(recognitionResults("claude take a photo"))
36+ advanceUntilIdle()
37+38+ listener.onReadyForSpeech(null)
39+ listener.onResults(recognitionResults("claude take a photo"))
40+ advanceUntilIdle()
41+42+ assertEquals(listOf("take a photo", "take a photo"), commands)
43+ }
44+45+private fun recognitionResults(text: String): Bundle =
46+Bundle().apply {
47+ putStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION, arrayListOf(text))
48+ }
49+50+private fun recognitionListener(manager: VoiceWakeManager): RecognitionListener {
51+val field = VoiceWakeManager::class.java.getDeclaredField("listener")
52+ field.isAccessible = true
53+return field.get(manager) as RecognitionListener
54+ }
55+}
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。