diff --git a/build.gradle b/build.gradle
index 576611ea..28ebe199 100755
--- a/build.gradle
+++ b/build.gradle
@@ -1,6 +1,6 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
- ext.kotlin_version = "1.2.51"
+ ext.kotlin_version = "1.3.10"
repositories {
google()
jcenter()
@@ -11,7 +11,7 @@ buildscript {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "org.jetbrains.kotlin:kotlin-android-extensions:$kotlin_version"
- classpath 'io.fabric.tools:gradle:1.+'
+ classpath 'io.fabric.tools:gradle:1.26.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
@@ -62,9 +62,7 @@ subprojects {
ext {
minSdkVersion = 19
targetSdkVersion = 27
- compileSdkVersion = 27
- buildToolsVersion = "27.0.3"
- kotlinVersion = "1.2.51"
- supportVersion = "27.0.1"
-
+ compileSdkVersion = 28
+ buildToolsVersion = "28.0.3"
+ supportVersion = "28.0.0"
}
\ No newline at end of file
diff --git a/mobile/build.gradle b/mobile/build.gradle
index 01f850bd..4f9102f1 100755
--- a/mobile/build.gradle
+++ b/mobile/build.gradle
@@ -44,6 +44,10 @@ android {
dataBinding {
enabled=true
}
+
+ testOptions {
+ unitTests.returnDefaultValues = true
+ }
}
repositories {
@@ -54,41 +58,36 @@ repositories {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation "com.android.support:appcompat-v7:$rootProject.supportVersion"
- implementation "com.android.support:design:$rootProject.supportVersion"
- implementation "com.android.support:support-v4:$rootProject.supportVersion"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$rootProject.kotlin_version"
- // layout deps
+ // Support Libraries and Google Play Services
+ implementation "com.android.support:appcompat-v7:$rootProject.supportVersion"
implementation "com.android.support:cardview-v7:$rootProject.supportVersion"
+ implementation "com.android.support:design:$rootProject.supportVersion"
implementation "com.android.support:recyclerview-v7:$rootProject.supportVersion"
+ implementation "com.android.support:support-core-utils:$rootProject.supportVersion"
+ implementation 'com.google.android.gms:play-services-wearable:16.0.1'
- implementation "com.android.support:palette-v7:$rootProject.supportVersion"
+ implementation 'org.java-websocket:Java-WebSocket:1.3.0'
- // Unit test dependencies
- testImplementation 'org.mockito:mockito-core:1.10.19'
- testImplementation 'org.powermock:powermock-api-mockito:1.6.4'
- testImplementation 'org.powermock:powermock-module-junit4-rule-agent:1.6.4'
- testImplementation 'org.powermock:powermock-module-junit4-rule:1.6.4'
- testImplementation 'org.powermock:powermock-module-junit4:1.6.4'
- testImplementation 'junit:junit:4.12'
- // Instrumentation dependencies
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:2.2.2'
- androidTestImplementation 'com.android.support.test:runner:0.5'
- androidTestImplementation "com.android.support:support-annotations:$rootProject.supportVersion"
- implementation('com.crashlytics.sdk.android:crashlytics:2.5.7@aar') {
+ implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
+ implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
+
+ implementation('com.crashlytics.sdk.android:crashlytics:2.9.6@aar') {
transitive = true
}
- implementation 'com.google.android.gms:play-services-wearable:9.4.0'
- wearApp project(':wear')
+
implementation project(':shared')
- //kotlin
- implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
- //rxjava,rxandroid
- implementation 'io.reactivex.rxjava2:rxjava:2.2.3'
- implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
+ wearApp project(':wear')
- implementation 'org.java-websocket:Java-WebSocket:1.3.0'
+ // Unit test dependencies
+ testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.3.1'
+ testImplementation 'org.junit.jupiter:junit-jupiter-api:5.3.1'
+ testImplementation 'io.mockk:mockk:1.8.13.kotlin13'
- implementation "com.android.support:support-core-utils:$rootProject.supportVersion"
+ // Instrumentation dependencies
+ androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ androidTestImplementation 'com.android.support.test:runner:1.0.2'
+ androidTestImplementation "com.android.support:support-annotations:$rootProject.supportVersion"
}
diff --git a/mobile/src/main/AndroidManifest.xml b/mobile/src/main/AndroidManifest.xml
index 8f7c9ceb..bf431d2b 100755
--- a/mobile/src/main/AndroidManifest.xml
+++ b/mobile/src/main/AndroidManifest.xml
@@ -27,7 +27,6 @@
-
-
.
- *
- */
-
-package mycroft.ai
-
-import android.content.Context
-import android.os.Bundle
-import android.util.Log
-
-import java.net.ServerSocket
-
-
-import android.net.nsd.NsdManager
-import android.net.nsd.NsdManager.DiscoveryListener
-import android.net.nsd.NsdManager.ResolveListener
-import android.net.nsd.NsdServiceInfo
-import android.annotation.SuppressLint
-import android.app.Activity
-
-@SuppressLint("NewApi")
-class DiscoveryActivity : Activity() {
-
- internal lateinit var mDiscoveryListener: DiscoveryListener
-
- internal var mServiceName: String? = null
- internal var mServiceInfo: NsdServiceInfo? = null
- internal var mServerSocket: ServerSocket? = null
- internal var mLocalPort: Int = 0
-
- internal lateinit var mNsdManager: NsdManager
-
- internal val TAG = "ServiceDiscovery"
- internal val SERVICE_TYPE = "_mycroft._tcp"
- internal val SERVICE_NAME = "MycroftAI Websocket"
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_main)
-
- mNsdManager = applicationContext.getSystemService(Context.NSD_SERVICE) as NsdManager
-
- initializeDiscoveryListener()
-
- mNsdManager.discoverServices(
- SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener)
-
- }
-
- fun initializeDiscoveryListener() {
-
- // Instantiate a new DiscoveryListener
- mDiscoveryListener = object : NsdManager.DiscoveryListener {
-
- // Called as soon as service discovery begins.
- override fun onDiscoveryStarted(regType: String) {
- Log.d(TAG, "Service discovery started")
- }
-
- override fun onServiceFound(service: NsdServiceInfo) {
- // A service was found! Do something with it.
- Log.d(TAG, "Service discovery success: $service")
- if (service.serviceType != SERVICE_TYPE) {
- // Service type is the string containing the protocol and
- // transport layer for this service.
- Log.d(TAG, "Mycroft found!: " + service.serviceType + " " + service.host + " " + service.port)
- resolveService(service)
- }
- }
-
- override fun onServiceLost(service: NsdServiceInfo) {
- // When the network service is no longer available.
- // Internal bookkeeping code goes here.
- Log.e(TAG, "service lost: $service")
- }
-
- override fun onDiscoveryStopped(serviceType: String) {
- Log.i(TAG, "Discovery stopped: $serviceType")
- }
-
- override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
- Log.e(TAG, "Discovery failed: Error code: $errorCode")
- mNsdManager.stopServiceDiscovery(this)
- }
-
- override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
- Log.e(TAG, "Discovery failed: Error code: $errorCode")
- mNsdManager.stopServiceDiscovery(this)
- }
- }
- }
-
- private fun resolveService(service: NsdServiceInfo) {
- mNsdManager.resolveService(service, object : ResolveListener {
-
- override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
- Log.d(TAG, "Resolving service...")
- Log.i(TAG, serviceInfo.host.toString())
- Log.i(TAG, "Port: " + serviceInfo.port)
- }
-
- override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
- // TODO Auto-generated method stub
- Log.d(TAG, "Service resolve failed!")
- }
- })
- }
-}
\ No newline at end of file
diff --git a/mobile/src/main/java/mycroft/ai/MainActivity.kt b/mobile/src/main/java/mycroft/ai/MainActivity.kt
index d3264582..eb5a9029 100644
--- a/mobile/src/main/java/mycroft/ai/MainActivity.kt
+++ b/mobile/src/main/java/mycroft/ai/MainActivity.kt
@@ -118,9 +118,6 @@ class MainActivity : AppCompatActivity() {
}
registerReceivers()
-
- // start the discovery activity (testing only)
- // startActivity(new Intent(this, DiscoveryActivity.class));
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
diff --git a/mobile/src/main/java/mycroft/ai/TTSManager.kt b/mobile/src/main/java/mycroft/ai/TTSManager.kt
index a183064c..65509d51 100755
--- a/mobile/src/main/java/mycroft/ai/TTSManager.kt
+++ b/mobile/src/main/java/mycroft/ai/TTSManager.kt
@@ -46,11 +46,14 @@ import java.util.Locale
*/
class TTSManager {
+ val notInitializedErrorMessage = "TTS Not Initialized"
+ val initializationFailedErrorMessage = "Initialization Failed!"
/**
* Backing TTS for this instance. Should not (ever) be null.
*/
private lateinit var mTts: TextToSpeech
+
/**
* Whether the TTS is available for use (i.e. loaded into memory)
*/
@@ -71,7 +74,7 @@ class TTSManager {
logError("This Language is not supported")
}
} else {
- logError("Initialization Failed!")
+ logError(initializationFailedErrorMessage)
}
}
@@ -108,7 +111,7 @@ class TTSManager {
if (isLoaded)
mTts.speak(text, TextToSpeech.QUEUE_ADD, null)
else {
- logError("TTS Not Initialized")
+ logError(notInitializedErrorMessage)
}
}
@@ -117,7 +120,7 @@ class TTSManager {
if (isLoaded)
mTts.speak(text, TextToSpeech.QUEUE_FLUSH, null)
else
- logError("TTS Not Initialized")
+ logError(notInitializedErrorMessage)
}
/**
diff --git a/mobile/src/main/java/mycroft/ai/utils/NetworkAutoDiscoveryUtil.kt b/mobile/src/main/java/mycroft/ai/utils/NetworkAutoDiscoveryUtil.kt
deleted file mode 100755
index 19cc2108..00000000
--- a/mobile/src/main/java/mycroft/ai/utils/NetworkAutoDiscoveryUtil.kt
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * Copyright (c) 2017. Mycroft AI, Inc.
- *
- * This file is part of Mycroft-Android a client for Mycroft Core.
- *
- * 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 mycroft.ai.utils
-
-import android.content.Context
-import android.net.nsd.NsdServiceInfo
-import android.net.nsd.NsdManager
-import android.util.Log
-
-/**
- * Created by paul on 2016/06/28.
- */
-class NetworkAutoDiscoveryUtil(internal var mContext: Context) {
- private var mServiceName = "MycroftAI Websocket"
- private var chosenServiceInfo: NsdServiceInfo? = null
- private var mNsdManager: NsdManager = mContext.getSystemService(Context.NSD_SERVICE) as NsdManager
-
- //declare late init as initialisation is after the fact.
- internal lateinit var mResolveListener: NsdManager.ResolveListener
-
- private var mDiscoveryListener: NsdManager.DiscoveryListener? = null
- private var mRegistrationListener: NsdManager.RegistrationListener? = null
-
-
- fun initializeNsd() {
- initializeResolveListener()
- //mNsdManager.init(mContext.getMainLooper(), this);
- }
-
- fun initializeDiscoveryListener() {
- mDiscoveryListener = object : NsdManager.DiscoveryListener {
- override fun onDiscoveryStarted(regType: String) {
- Log.d(TAG, "Service discovery started")
- }
-
- override fun onServiceFound(service: NsdServiceInfo) {
- Log.d(TAG, "Service discovery success$service")
- if (service.serviceType != SERVICE_TYPE) {
- Log.d(TAG, "Unknown Service Type: " + service.serviceType)
- } else if (service.serviceName == mServiceName) {
- Log.d(TAG, "Same machine: $mServiceName")
- } else if (service.serviceName.contains(mServiceName)) {
- mNsdManager.resolveService(service, mResolveListener)
- }
- }
-
- override fun onServiceLost(service: NsdServiceInfo) {
- Log.e(TAG, "service lost$service")
- if (chosenServiceInfo == service) {
- chosenServiceInfo = null
- }
- }
-
- override fun onDiscoveryStopped(serviceType: String) {
- Log.i(TAG, "Discovery stopped: $serviceType")
- }
-
- override fun onStartDiscoveryFailed(serviceType: String, errorCode: Int) {
- Log.e(TAG, "Discovery failed: Error code:$errorCode")
- }
-
- override fun onStopDiscoveryFailed(serviceType: String, errorCode: Int) {
- Log.e(TAG, "Discovery failed: Error code:$errorCode")
- }
- }
- }
-
- fun initializeResolveListener() {
- mResolveListener = object : NsdManager.ResolveListener {
- override fun onResolveFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
- Log.e(TAG, "Resolve failed$errorCode")
- }
-
- override fun onServiceResolved(serviceInfo: NsdServiceInfo) {
- Log.e(TAG, "Resolve Succeeded. $serviceInfo")
- if (serviceInfo.serviceName == mServiceName) {
- Log.d(TAG, "Same IP.")
- return
- }
- chosenServiceInfo = serviceInfo
- }
- }
- }
-
- fun initializeRegistrationListener() {
- mRegistrationListener = object : NsdManager.RegistrationListener {
- override fun onServiceRegistered(NsdServiceInfo: NsdServiceInfo) {
- mServiceName = NsdServiceInfo.serviceName
- Log.d(TAG, "Service registered: $mServiceName")
- }
-
- override fun onRegistrationFailed(arg0: NsdServiceInfo, arg1: Int) {
- Log.d(TAG, "Service registration failed: $arg1")
- }
-
- override fun onServiceUnregistered(arg0: NsdServiceInfo) {
- Log.d(TAG, "Service unregistered: " + arg0.serviceName)
- }
-
- override fun onUnregistrationFailed(serviceInfo: NsdServiceInfo, errorCode: Int) {
- Log.d(TAG, "Service unregistration failed: $errorCode")
- }
- }
- }
-
- fun registerService(port: Int) {
- tearDown() // Cancel any previous registration request
- initializeRegistrationListener()
- val serviceInfo = NsdServiceInfo()
- serviceInfo.port = port
- serviceInfo.serviceName = mServiceName
- serviceInfo.serviceType = SERVICE_TYPE
- mNsdManager.registerService(
- serviceInfo, NsdManager.PROTOCOL_DNS_SD, mRegistrationListener)
- }
-
- fun discoverServices() {
- stopDiscovery() // Cancel any existing discovery request
- initializeDiscoveryListener()
- mNsdManager.discoverServices(
- SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, mDiscoveryListener)
- }
-
- fun stopDiscovery() {
- if (mDiscoveryListener != null) {
- try {
- mNsdManager.stopServiceDiscovery(mDiscoveryListener)
- } finally {
- }
- mDiscoveryListener = null
- }
- }
-
- fun tearDown() {
- if (mRegistrationListener != null) {
- try {
- mNsdManager.unregisterService(mRegistrationListener)
- } finally {
- }
- mRegistrationListener = null
- }
- }
-
- companion object {
-
- private val TAG = "NetworkDiscovery"
- private val SERVICE_TYPE = " _mycroft._tcp"
- }
-}
diff --git a/mobile/src/test/java/mycroft/ai/ExampleUnitTest.java b/mobile/src/test/java/mycroft/ai/ExampleUnitTest.java
deleted file mode 100755
index 5de091b1..00000000
--- a/mobile/src/test/java/mycroft/ai/ExampleUnitTest.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (c) 2017. Mycroft AI, Inc.
- *
- * This file is part of Mycroft-Android a client for Mycroft Core.
- *
- * 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 mycroft.ai;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see Testing documentation
- */
-public class ExampleUnitTest {
- @Test
- public void addition_isCorrect() throws Exception {
- assertEquals(4, 2 + 2);
- }
-}
\ No newline at end of file
diff --git a/mobile/src/test/java/mycroft/ai/LogAnswer.java b/mobile/src/test/java/mycroft/ai/LogAnswer.java
deleted file mode 100755
index 96396391..00000000
--- a/mobile/src/test/java/mycroft/ai/LogAnswer.java
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2017. Mycroft AI, Inc.
- *
- * This file is part of Mycroft-Android a client for Mycroft Core.
- *
- * 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 mycroft.ai;
-
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-
-import java.io.PrintStream;
-import java.nio.charset.Charset;
-import java.util.Locale;
-
-/**
- * Useful for mocking {@link android.util.Log} static methods.
- *
- * Use it like so:
- * {@code
- * Mockito.when(Log.v(anyString(), anyString())).then(new LogAnswer(System.out));
- * }
- *
- *
- * @author Philip Cohn-Cort
- */
-public class LogAnswer implements Answer {
-
- protected final PrintStream stream;
-
- public LogAnswer(PrintStream stream) {
- this.stream = stream;
- }
-
- @Override
- public Integer answer(InvocationOnMock invocation) throws Throwable {
- String tag = invocation.getArgumentAt(0, String.class);
- String msg = invocation.getArgumentAt(1, String.class);
-
- String name = invocation.getMethod().getName();
-
- String format = String.format(Locale.US, "[Log.%s] %s: %s", name, tag, msg);
- stream.println(format);
-
- return format.getBytes(Charset.forName("UTF8")).length;
- }
-}
\ No newline at end of file
diff --git a/mobile/src/test/java/mycroft/ai/TTSManagerTest.java b/mobile/src/test/java/mycroft/ai/TTSManagerTest.java
deleted file mode 100755
index 15127220..00000000
--- a/mobile/src/test/java/mycroft/ai/TTSManagerTest.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * Copyright (c) 2017. Mycroft AI, Inc.
- *
- * This file is part of Mycroft-Android a client for Mycroft Core.
- *
- * 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 mycroft.ai;
-
-import android.os.Bundle;
-import android.speech.tts.TextToSpeech;
-import android.util.Log;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.powermock.core.classloader.annotations.PrepareForTest;
-import org.powermock.modules.junit4.PowerMockRunner;
-
-import java.util.HashMap;
-import java.util.Locale;
-
-import static org.junit.Assert.*;
-import static org.mockito.Matchers.any;
-import static org.mockito.Matchers.anyString;
-import static org.mockito.Mockito.atLeast;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.powermock.api.mockito.PowerMockito.mock;
-import static org.powermock.api.mockito.PowerMockito.mockStatic;
-import static org.powermock.api.mockito.PowerMockito.when;
-
-/**
- * @author Philip Cohn-Cort
- */
-@RunWith(PowerMockRunner.class)
-@PrepareForTest({Log.class})
-public class TTSManagerTest {
-
- @Before
- public void setUp() throws Exception {
- mockStatic(Log.class);
-
- LogAnswer stdOut = new LogAnswer(System.out);
- when(Log.v(anyString(), anyString())).then(stdOut);
- when(Log.d(anyString(), anyString())).then(stdOut);
- when(Log.i(anyString(), anyString())).then(stdOut);
-
- LogAnswer stdErr = new LogAnswer(System.err);
- when(Log.w(anyString(), anyString())).then(stdErr);
- when(Log.e(anyString(), anyString())).then(stdErr);
- when(Log.wtf(anyString(), anyString())).then(stdErr);
- }
-
- @Test
- public void testAddingToQueueBeforeIsLoaded() throws Exception {
- TextToSpeech mock = mock(TextToSpeech.class);
- TTSManager ttsManager = new TTSManager(mock);
-
- TTSManager.TTSListener mockListener = mock(TTSManager.TTSListener.class);
- ttsManager.setTTSListener(mockListener);
-
- ttsManager.addQueue("text a");
-
- verify(mockListener).onError("TTS Not Initialized");
- }
-
- @Test
- public void testAddingToQueueAfterIsLoaded() throws Exception {
- TextToSpeech tts = mock(TextToSpeech.class);
- when(tts.setLanguage(any(Locale.class))).thenReturn(TextToSpeech.LANG_AVAILABLE);
-
- TTSManager ttsManager = new TTSManager(tts);
-
- TTSManager.TTSListener mockListener = mock(TTSManager.TTSListener.class);
- ttsManager.setTTSListener(mockListener);
-
- ttsManager.getOnInitListener().onInit(TextToSpeech.SUCCESS);
-
- verify(mockListener, never()).onError(anyString());
-
- ttsManager.addQueue("text a");
-
- verify(mockListener, never()).onError(anyString());
- }
-
- @Test
- public void testAddingToQueueTriggersSpeak() throws Exception {
- TextToSpeech tts = mock(TextToSpeech.class);
- when(tts.setLanguage(any(Locale.class))).thenReturn(TextToSpeech.LANG_AVAILABLE);
-
- TTSManager ttsManager = new TTSManager(tts);
-
- TTSManager.TTSListener mockListener = mock(TTSManager.TTSListener.class);
- ttsManager.setTTSListener(mockListener);
-
- ttsManager.getOnInitListener().onInit(TextToSpeech.SUCCESS);
-
- ttsManager.addQueue("text a");
-
- // Make sure that one of the speak methods was called, but we don't care which
-
- ArgumentCaptor paramCaptor1 = ArgumentCaptor.forClass(Integer.class);
- ArgumentCaptor paramCaptor2 = ArgumentCaptor.forClass(Integer.class);
-
- //noinspection unchecked
- verify(tts, atLeast(0)).speak(anyString(), paramCaptor1.capture(), any(HashMap.class));
- verify(tts, atLeast(0)).speak(any(CharSequence.class), paramCaptor2.capture(), any(Bundle.class), anyString());
-
- assertTrue("One of the speak methods should have been called.",
- !paramCaptor1.getAllValues().isEmpty()
- ||
- !paramCaptor2.getAllValues().isEmpty()
- );
- }
-
- @Test
- public void testFailureDoesNotSetIsLoaded() throws Exception {
- TextToSpeech tts = mock(TextToSpeech.class);
- when(tts.setLanguage(any(Locale.class))).thenReturn(TextToSpeech.LANG_AVAILABLE);
-
- TTSManager ttsManager = new TTSManager(tts);
-
- TTSManager.TTSListener mockListener = mock(TTSManager.TTSListener.class);
- ttsManager.setTTSListener(mockListener);
-
- ttsManager.getOnInitListener().onInit(TextToSpeech.ERROR);
-
- ttsManager.addQueue("text a");
-
- verify(mockListener, times(2)).onError(anyString());
- }
-}
\ No newline at end of file
diff --git a/mobile/src/test/java/mycroft/ai/TTSManagerTest.kt b/mobile/src/test/java/mycroft/ai/TTSManagerTest.kt
new file mode 100644
index 00000000..7ec6e8bd
--- /dev/null
+++ b/mobile/src/test/java/mycroft/ai/TTSManagerTest.kt
@@ -0,0 +1,61 @@
+package mycroft.ai
+
+import android.speech.tts.TextToSpeech
+import io.mockk.impl.annotations.RelaxedMockK
+import io.mockk.junit5.MockKExtension
+import io.mockk.verify
+import org.junit.jupiter.api.BeforeEach
+import org.junit.jupiter.api.Test
+
+import org.junit.jupiter.api.extension.ExtendWith
+
+@ExtendWith(MockKExtension::class)
+class TTSManagerTest {
+ private val someSpeech = "some speech"
+
+ private lateinit var subject: TTSManager
+
+ @RelaxedMockK
+ private lateinit var textToSpeech: TextToSpeech
+
+ @RelaxedMockK
+ private lateinit var ttsListener: TTSManager.TTSListener
+
+ @BeforeEach
+ fun setUp() {
+ subject = TTSManager(textToSpeech)
+ }
+
+ @Test
+ fun testAddQueue_BeforeIsLoaded_CallsOnError() {
+ subject.setTTSListener(ttsListener)
+ subject.addQueue(someSpeech)
+
+ verify(exactly = 1) { ttsListener.onError(eq(subject.notInitializedErrorMessage)) }
+ }
+
+ @Test
+ fun testAddQueue_WhenLoaded_DoesNotCallOnError() {
+ subject.onInitListener.onInit(TextToSpeech.SUCCESS)
+ verify(exactly = 0) { ttsListener.onError(any()) }
+ subject.addQueue(someSpeech)
+ verify(exactly = 0) { ttsListener.onError(any()) }
+ }
+
+ @Test
+ fun testAddQueue_WhenLoaded_TriggersSpeak() {
+ subject.onInitListener.onInit(TextToSpeech.SUCCESS)
+ subject.addQueue(someSpeech)
+ verify(exactly = 1) { textToSpeech.speak(any(), any(), any()) }
+ }
+
+ @Test
+ fun testInitFailure_DoesNotSetLoadedTrue() {
+ subject.setTTSListener(ttsListener)
+ subject.onInitListener.onInit(TextToSpeech.ERROR)
+ subject.addQueue(someSpeech)
+ verify(exactly = 1) { ttsListener.onError(eq(subject.initializationFailedErrorMessage)) }
+ verify(exactly = 1) { ttsListener.onError(eq(subject.notInitializedErrorMessage)) }
+
+ }
+}
\ No newline at end of file