Initial commit: Voice controlled device application, specs and Gitea Actions workflow
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
package com.example.voiceapp.domain
|
||||
|
||||
import com.example.voiceapp.domain.executor.GetTimeDateExecutor
|
||||
import com.example.voiceapp.domain.executor.SetAlarmTimerExecutor
|
||||
import com.example.voiceapp.domain.model.CommandId
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class CommandParserTest {
|
||||
private lateinit var parser: CommandParser
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
val definitions = listOf(
|
||||
CommandDefinition(CommandId.GET_TIME_DATE, listOf(Regex(".*(今何時|何時ですか|日付|今日).*")), GetTimeDateExecutor()),
|
||||
CommandDefinition(CommandId.SET_ALARM_TIMER, listOf(Regex(".*(\\d+)\\s*(分|秒|時間)の?タイマー.*"), Regex(".*(\\d+)\\s*時にアラーム.*")), SetAlarmTimerExecutor())
|
||||
)
|
||||
parser = CommandParser(definitions)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parse_getTime_returnsGetTimeDateCommand() {
|
||||
val result = parser.parse("今何時?")
|
||||
assertEquals(CommandId.GET_TIME_DATE, result.commandId)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parse_setTimer_withKanji_returnsSetAlarmTimerCommand() {
|
||||
val result = parser.parse("三分タイマーかけて")
|
||||
assertEquals(CommandId.SET_ALARM_TIMER, result.commandId)
|
||||
assertEquals("3", result.extractedParameters["value"])
|
||||
assertEquals("分", result.extractedParameters["unit"])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parse_unknownText_returnsUnknownFallback() {
|
||||
val result = parser.parse("こんにちは")
|
||||
assertEquals(CommandId.UNKNOWN_FALLBACK, result.commandId)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.voiceapp.domain
|
||||
|
||||
import com.example.voiceapp.domain.executor.GetTimeDateExecutor
|
||||
import com.example.voiceapp.domain.model.CommandId
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
class ExecuteCommandUseCaseTest {
|
||||
private lateinit var useCase: ExecuteCommandUseCase
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
val definitions = listOf(
|
||||
CommandDefinition(CommandId.GET_TIME_DATE, listOf(Regex(".*(今何時|何時ですか|日付|今日).*")), GetTimeDateExecutor())
|
||||
)
|
||||
val parser = CommandParser(definitions)
|
||||
useCase = ExecuteCommandUseCase(parser)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun invoke_getTime_returnsSuccessResult() = runTest {
|
||||
val result = useCase("今何時")
|
||||
assertEquals(CommandId.GET_TIME_DATE, result.commandId)
|
||||
assertTrue(result.isSuccess)
|
||||
assertTrue(result.responseText.contains("現在"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.example.voiceapp.domain
|
||||
|
||||
import com.example.voiceapp.domain.converter.KanjiToNumberConverter
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
|
||||
class KanjiToNumberConverterTest {
|
||||
|
||||
@Test
|
||||
fun convert_kanjiDigits_convertsToNumbers() {
|
||||
assertEquals("3分", KanjiToNumberConverter.convert("三分"))
|
||||
assertEquals("7時", KanjiToNumberConverter.convert("七時"))
|
||||
assertEquals("15分", KanjiToNumberConverter.convert("十五分"))
|
||||
assertEquals("3分", KanjiToNumberConverter.convert("3 minutes"))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.example.voiceapp.ui
|
||||
|
||||
import app.cash.turbine.test
|
||||
import com.example.voiceapp.domain.ExecuteCommandUseCase
|
||||
import com.example.voiceapp.domain.model.CommandId
|
||||
import com.example.voiceapp.domain.model.CommandResult
|
||||
import com.example.voiceapp.voice.ITextToSpeech
|
||||
import com.example.voiceapp.voice.IVoiceRecognizer
|
||||
import com.example.voiceapp.voice.TtsStatus
|
||||
import com.example.voiceapp.voice.VoiceRecognitionState
|
||||
import io.mockk.coEvery
|
||||
import io.mockk.every
|
||||
import io.mockk.mockk
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.resetMain
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import kotlinx.coroutines.test.setMain
|
||||
import org.junit.After
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
class MainViewModelTest {
|
||||
private val testDispatcher = StandardTestDispatcher()
|
||||
private val useCase: ExecuteCommandUseCase = mockk()
|
||||
private val recognizer: IVoiceRecognizer = mockk(relaxed = true)
|
||||
private val tts: ITextToSpeech = mockk(relaxed = true)
|
||||
|
||||
private val recognizerState = MutableStateFlow<VoiceRecognitionState>(VoiceRecognitionState.Idle)
|
||||
private val rmsDbState = MutableStateFlow(0f)
|
||||
private val ttsStatusState = MutableStateFlow<TtsStatus>(TtsStatus.Idle)
|
||||
|
||||
private lateinit var viewModel: MainViewModel
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
Dispatchers.setMain(testDispatcher)
|
||||
every { recognizer.state } returns recognizerState
|
||||
every { recognizer.rmsDb } returns rmsDbState
|
||||
every { tts.status } returns ttsStatusState
|
||||
|
||||
viewModel = MainViewModel(useCase, recognizer, tts)
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
Dispatchers.resetMain()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun processUserSpeech_updatesHistoryAndState() = runTest {
|
||||
coEvery { useCase("今何時") } returns CommandResult(CommandId.GET_TIME_DATE, true, "現在は10時00分です。")
|
||||
|
||||
viewModel.processUserSpeech("今何時")
|
||||
testDispatcher.scheduler.advanceUntilIdle()
|
||||
|
||||
viewModel.conversationHistory.test {
|
||||
val history = awaitItem()
|
||||
assertEquals(2, history.size)
|
||||
assertEquals("今何時", history[0].text)
|
||||
assertEquals("現在は10時00分です。", history[1].text)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user