summaryrefslogtreecommitdiffstats
path: root/tests/TtsTests
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2011-12-06 16:40:03 +0000
committerNarayan Kamath <narayan@google.com>2012-01-09 13:38:55 +0000
commitc60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5 (patch)
tree0e6498b4164abed862acc6cc14788a7d2b60a9a9 /tests/TtsTests
parent9a03482c66b2f5c30c7fde38216239a1f233df02 (diff)
downloadframeworks_base-c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5.zip
frameworks_base-c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5.tar.gz
frameworks_base-c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5.tar.bz2
Write unit tests for android.speech.tts.
Change-Id: Ie5b3b4cdd13be2babee9a44bae00da179b372d12
Diffstat (limited to 'tests/TtsTests')
-rw-r--r--tests/TtsTests/Android.mk28
-rw-r--r--tests/TtsTests/AndroidManifest.xml43
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java58
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java78
-rw-r--r--tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java229
5 files changed, 436 insertions, 0 deletions
diff --git a/tests/TtsTests/Android.mk b/tests/TtsTests/Android.mk
new file mode 100644
index 0000000..e049c90
--- /dev/null
+++ b/tests/TtsTests/Android.mk
@@ -0,0 +1,28 @@
+#
+# Copyright (C) 2011 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_STATIC_JAVA_LIBRARIES := littlemock
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := TtsTests
+
+include $(BUILD_PACKAGE)
diff --git a/tests/TtsTests/AndroidManifest.xml b/tests/TtsTests/AndroidManifest.xml
new file mode 100644
index 0000000..b6d5111
--- /dev/null
+++ b/tests/TtsTests/AndroidManifest.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Copyright (C) 2011 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.speech.tts">
+ <application>
+ <uses-library android:name="android.test.runner" />
+
+
+ <service android:name=".MockableTextToSpeechService"
+ android:label="Mockable Text-to-speech Service">
+ <intent-filter>
+ <action android:name="android.intent.action.TTS_SERVICE" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </service>
+
+ <activity android:name=".MockableCheckVoiceData"
+ android:theme="@android:style/Theme.NoDisplay">
+ <intent-filter>
+ <action android:name="android.speech.tts.engine.CHECK_TTS_DATA" />
+ <category android:name="android.intent.category.DEFAULT" />
+ </intent-filter>
+ </activity>
+ </application>
+
+ <instrumentation android:name="android.test.InstrumentationTestRunner"
+ android:targetPackage="com.android.speech.tts"
+ android:label="Tests for android.speech.tts" />
+</manifest>
diff --git a/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java b/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java
new file mode 100644
index 0000000..0ab8ed6
--- /dev/null
+++ b/tests/TtsTests/src/com/android/speech/tts/MockableCheckVoiceData.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.speech.tts;
+
+import android.app.Activity;
+import android.content.Intent;
+import android.os.Bundle;
+import android.speech.tts.TextToSpeech;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MockableCheckVoiceData extends Activity {
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ MockableTextToSpeechService.IDelegate delegate =
+ MockableTextToSpeechService.getMocker();
+
+ ArrayList<String> availableLangs = delegate.getAvailableVoices();
+ ArrayList<String> unavailableLangs = delegate.getUnavailableVoices();
+
+ final Intent returnVal = new Intent();
+
+ // Returns early.
+ if (availableLangs == null) {
+ setResult(TextToSpeech.Engine.CHECK_VOICE_DATA_FAIL, returnVal);
+ finish();
+ return;
+ }
+
+ returnVal.putStringArrayListExtra(TextToSpeech.Engine.EXTRA_AVAILABLE_VOICES,
+ availableLangs);
+
+ if (unavailableLangs != null && unavailableLangs.size() > 0) {
+ returnVal.putStringArrayListExtra(TextToSpeech.Engine.EXTRA_UNAVAILABLE_VOICES,
+ unavailableLangs);
+ }
+
+ setResult(TextToSpeech.Engine.CHECK_VOICE_DATA_PASS, returnVal);
+ finish();
+ }
+
+}
diff --git a/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java
new file mode 100644
index 0000000..20648a4
--- /dev/null
+++ b/tests/TtsTests/src/com/android/speech/tts/MockableTextToSpeechService.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.speech.tts;
+
+import android.speech.tts.SynthesisCallback;
+import android.speech.tts.SynthesisRequest;
+import android.speech.tts.TextToSpeechService;
+
+import java.util.ArrayList;
+
+public class MockableTextToSpeechService extends TextToSpeechService {
+
+ private static IDelegate sDelegate;
+
+ public static void setMocker(IDelegate delegate) {
+ sDelegate = delegate;
+ }
+
+ static IDelegate getMocker() {
+ return sDelegate;
+ }
+
+ @Override
+ protected int onIsLanguageAvailable(String lang, String country, String variant) {
+ return sDelegate.onIsLanguageAvailable(lang, country, variant);
+ }
+
+ @Override
+ protected String[] onGetLanguage() {
+ return sDelegate.onGetLanguage();
+ }
+
+ @Override
+ protected int onLoadLanguage(String lang, String country, String variant) {
+ return sDelegate.onLoadLanguage(lang, country, variant);
+ }
+
+ @Override
+ protected void onStop() {
+ sDelegate.onStop();
+ }
+
+ @Override
+ protected void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback) {
+ sDelegate.onSynthesizeText(request, callback);
+ }
+
+ public static interface IDelegate {
+ int onIsLanguageAvailable(String lang, String country, String variant);
+
+ String[] onGetLanguage();
+
+ int onLoadLanguage(String lang, String country, String variant);
+
+ void onStop();
+
+ void onSynthesizeText(SynthesisRequest request, SynthesisCallback callback);
+
+ ArrayList<String> getAvailableVoices();
+
+ ArrayList<String> getUnavailableVoices();
+ }
+
+}
diff --git a/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
new file mode 100644
index 0000000..b736e9f
--- /dev/null
+++ b/tests/TtsTests/src/com/android/speech/tts/TextToSpeechTests.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.speech.tts;
+
+import android.speech.tts.SynthesisCallback;
+import android.speech.tts.SynthesisRequest;
+import android.speech.tts.TextToSpeech;
+import android.test.InstrumentationTestCase;
+
+import com.android.speech.tts.MockableTextToSpeechService.IDelegate;
+import com.google.testing.littlemock.ArgumentCaptor;
+import com.google.testing.littlemock.Behaviour;
+import com.google.testing.littlemock.LittleMock;
+import junit.framework.Assert;
+
+import java.util.Locale;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+public class TextToSpeechTests extends InstrumentationTestCase {
+ private static final String MOCK_ENGINE = "com.android.speech.tts";
+ private static final String MOCK_PACKAGE = "com.android.speech.tts.__testpackage__";
+
+ private TextToSpeech mTts;
+
+ @Override
+ public void setUp() throws Exception {
+ IDelegate passThrough = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(passThrough);
+
+ blockingInitAndVerify(MOCK_ENGINE, TextToSpeech.SUCCESS);
+ assertEquals(MOCK_ENGINE, mTts.getCurrentEngine());
+ }
+
+
+ @Override
+ public void tearDown() {
+ if (mTts != null) {
+ mTts.shutdown();
+ }
+ }
+
+ public void testEngineInitialized() throws Exception {
+ // Fail on an engine that doesn't exist.
+ blockingInitAndVerify("__DOES_NOT_EXIST__", TextToSpeech.ERROR);
+
+ // Also, the "current engine" must be null
+ assertNull(mTts.getCurrentEngine());
+ }
+
+ public void testSetLanguage_delegation() {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the
+ // service without any caching or intermediate steps.
+ mTts.setLanguage(new Locale("eng", "USA", "variant"));
+ LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage(
+ "eng", "USA", "variant");
+ }
+
+ public void testSetLanguage_availableLanguage() throws Exception {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // ---------------------------------------------------------
+ // Test 2 : Tests that when the language is successfully set
+ // like above (returns LANG_COUNTRY_AVAILABLE). That the
+ // request language changes from that point on.
+ LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
+ "eng", "USA", "variant");
+ mTts.setLanguage(new Locale("eng", "USA", "variant"));
+ blockingCallSpeak("foo bar", delegate);
+ ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor();
+ LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(),
+ LittleMock.<SynthesisCallback>anyObject());
+
+ assertEquals("eng", req.getValue().getLanguage());
+ assertEquals("USA", req.getValue().getCountry());
+ assertEquals("", req.getValue().getVariant());
+ }
+
+ public void testSetLanguage_unavailableLanguage() throws Exception {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // ---------------------------------------------------------
+ // TEST 3 : Tests that the language that is set does not change when the
+ // engine reports it could not load the specified language.
+ LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when(
+ delegate).onLoadLanguage("fra", "FRA", "");
+ mTts.setLanguage(Locale.FRANCE);
+ blockingCallSpeak("le fou barre", delegate);
+ ArgumentCaptor<SynthesisRequest> req2 = LittleMock.createCaptor();
+ LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req2.capture(),
+ LittleMock.<SynthesisCallback>anyObject());
+
+ // The params are basically unchanged.
+ assertEquals("eng", req2.getValue().getLanguage());
+ assertEquals("USA", req2.getValue().getCountry());
+ assertEquals("", req2.getValue().getVariant());
+ }
+
+
+ public void testGetLanguage_invalidReturnValues() {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // Test1: Simple end to end test. Ensure that bad return values
+ // are dealt with appropriately.
+ LittleMock.doReturn(null).when(delegate).onGetLanguage();
+ Locale returnVal = mTts.getLanguage();
+ assertNull(returnVal);
+
+
+ // Bad value 2. An array of length < 3.
+ LittleMock.doReturn(new String[] {"eng", "usa"}).when(delegate).onGetLanguage();
+ returnVal = mTts.getLanguage();
+ assertNull(returnVal);
+ }
+
+ public void testGetLanguage_validReturnValues() {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // A correct value.
+ LittleMock.doReturn(new String[] {"eng", "usa", ""}).when(delegate).onGetLanguage();
+ Locale returnVal = mTts.getLanguage();
+
+ // Note: This is not the same as Locale.US . Well tough luck for
+ // being the only component of the entire framework that standardized
+ // three letter country and language codes.
+ assertEquals(new Locale("eng", "USA", ""), returnVal);
+ }
+
+ public void testIsLanguageAvailable() {
+ IDelegate delegate = LittleMock.mock(IDelegate.class);
+ MockableTextToSpeechService.setMocker(delegate);
+
+ // Test1: Simple end to end test.
+ LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(
+ delegate).onIsLanguageAvailable("eng", "USA", "");
+
+ assertEquals(TextToSpeech.LANG_COUNTRY_AVAILABLE, mTts.isLanguageAvailable(Locale.US));
+ LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable(
+ "eng", "USA", "");
+ }
+
+
+ private void blockingCallSpeak(String speech, IDelegate mock) throws
+ InterruptedException {
+ final CountDownLatch latch = new CountDownLatch(1);
+ doCountDown(latch).when(mock).onSynthesizeText(LittleMock.<SynthesisRequest>anyObject(),
+ LittleMock.<SynthesisCallback>anyObject());
+ mTts.speak(speech, TextToSpeech.QUEUE_ADD, null);
+
+ awaitCountDown(latch, 5, TimeUnit.SECONDS);
+ }
+
+ private void blockingInitAndVerify(final String engine, int errorCode) throws
+ InterruptedException {
+ TextToSpeech.OnInitListener listener = LittleMock.mock(
+ TextToSpeech.OnInitListener.class);
+
+ final CountDownLatch latch = new CountDownLatch(1);
+ doCountDown(latch).when(listener).onInit(errorCode);
+
+ mTts = new TextToSpeech(getInstrumentation().getTargetContext(),
+ listener, engine, MOCK_PACKAGE, false /* use fallback package */);
+
+ awaitCountDown(latch, 5, TimeUnit.SECONDS);
+ }
+
+ public interface CountDownBehaviour extends Behaviour {
+ /** Used to mock methods that return a result. */
+ Behaviour andReturn(Object result);
+ }
+
+ public static CountDownBehaviour doCountDown(final CountDownLatch latch) {
+ return new CountDownBehaviour() {
+ @Override
+ public <T> T when(T mock) {
+ return LittleMock.doAnswer(new Callable<Void>() {
+ @Override
+ public Void call() throws Exception {
+ latch.countDown();
+ return null;
+ }
+ }).when(mock);
+ }
+
+ @Override
+ public Behaviour andReturn(final Object result) {
+ return new Behaviour() {
+ @Override
+ public <T> T when(T mock) {
+ return LittleMock.doAnswer(new Callable<Object>() {
+ @Override
+ public Object call() throws Exception {
+ latch.countDown();
+ return result;
+ }
+ }).when(mock);
+ }
+ };
+ }
+ };
+ }
+
+ public static void awaitCountDown(CountDownLatch latch, long timeout, TimeUnit unit)
+ throws InterruptedException {
+ Assert.assertTrue("Waited too long for method call", latch.await(timeout, unit));
+ }
+}