|
|
|
|
@@ -22,9 +22,12 @@ 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 org.mockito.ArgumentCaptor;
|
|
|
|
|
import org.mockito.Mockito;
|
|
|
|
|
import org.mockito.internal.stubbing.StubberImpl;
|
|
|
|
|
import org.mockito.invocation.InvocationOnMock;
|
|
|
|
|
import org.mockito.stubbing.Answer;
|
|
|
|
|
import org.mockito.stubbing.Stubber;
|
|
|
|
|
import junit.framework.Assert;
|
|
|
|
|
|
|
|
|
|
import java.util.Locale;
|
|
|
|
|
@@ -40,16 +43,16 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public void setUp() throws Exception {
|
|
|
|
|
IDelegate passThrough = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate passThrough = Mockito.mock(IDelegate.class);
|
|
|
|
|
MockableTextToSpeechService.setMocker(passThrough);
|
|
|
|
|
|
|
|
|
|
// For the default voice selection
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough)
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough)
|
|
|
|
|
.onIsLanguageAvailable(
|
|
|
|
|
LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString());
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough)
|
|
|
|
|
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(passThrough)
|
|
|
|
|
.onLoadLanguage(
|
|
|
|
|
LittleMock.anyString(), LittleMock.anyString(), LittleMock.anyString());
|
|
|
|
|
Mockito.anyString(), Mockito.anyString(), Mockito.anyString());
|
|
|
|
|
|
|
|
|
|
blockingInitAndVerify(MOCK_ENGINE, TextToSpeech.SUCCESS);
|
|
|
|
|
assertEquals(MOCK_ENGINE, mTts.getCurrentEngine());
|
|
|
|
|
@@ -71,42 +74,42 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void testSetLanguage_delegation() {
|
|
|
|
|
IDelegate delegate = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate delegate = Mockito.mock(IDelegate.class);
|
|
|
|
|
MockableTextToSpeechService.setMocker(delegate);
|
|
|
|
|
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onIsLanguageAvailable(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onIsLanguageAvailable(
|
|
|
|
|
"eng", "USA", "variant");
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onLoadLanguage(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE).when(delegate).onLoadLanguage(
|
|
|
|
|
"eng", "USA", "variant");
|
|
|
|
|
|
|
|
|
|
// Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the
|
|
|
|
|
// service without any caching or intermediate steps.
|
|
|
|
|
assertEquals(TextToSpeech.LANG_COUNTRY_VAR_AVAILABLE, mTts.setLanguage(new Locale("eng", "USA", "variant")));
|
|
|
|
|
LittleMock.verify(delegate, LittleMock.anyTimes()).onIsLanguageAvailable(
|
|
|
|
|
Mockito.verify(delegate, Mockito.atLeast(0)).onIsLanguageAvailable(
|
|
|
|
|
"eng", "USA", "variant");
|
|
|
|
|
LittleMock.verify(delegate, LittleMock.anyTimes()).onLoadLanguage(
|
|
|
|
|
Mockito.verify(delegate, Mockito.atLeast(0)).onLoadLanguage(
|
|
|
|
|
"eng", "USA", "variant");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void testSetLanguage_availableLanguage() throws Exception {
|
|
|
|
|
IDelegate delegate = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate delegate = Mockito.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).onIsLanguageAvailable(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
|
|
|
|
|
"eng", "USA", "variant");
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable(
|
|
|
|
|
"eng", "USA", "");
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage(
|
|
|
|
|
"eng", "USA", "");
|
|
|
|
|
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());
|
|
|
|
|
ArgumentCaptor<SynthesisRequest> req = ArgumentCaptor.forClass(SynthesisRequest.class);
|
|
|
|
|
Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req.capture(),
|
|
|
|
|
Mockito.<SynthesisCallback>anyObject());
|
|
|
|
|
|
|
|
|
|
assertEquals("eng", req.getValue().getLanguage());
|
|
|
|
|
assertEquals("USA", req.getValue().getCountry());
|
|
|
|
|
@@ -115,21 +118,21 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void testSetLanguage_unavailableLanguage() throws Exception {
|
|
|
|
|
IDelegate delegate = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate delegate = Mockito.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(
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when(
|
|
|
|
|
delegate).onIsLanguageAvailable("fra", "FRA", "");
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when(
|
|
|
|
|
Mockito.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());
|
|
|
|
|
ArgumentCaptor<SynthesisRequest> req2 = ArgumentCaptor.forClass(SynthesisRequest.class);
|
|
|
|
|
Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req2.capture(),
|
|
|
|
|
Mockito.<SynthesisCallback>anyObject());
|
|
|
|
|
|
|
|
|
|
// The params are basically unchanged.
|
|
|
|
|
assertEquals("eng", req2.getValue().getLanguage());
|
|
|
|
|
@@ -139,41 +142,41 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void testIsLanguageAvailable() {
|
|
|
|
|
IDelegate delegate = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate delegate = Mockito.mock(IDelegate.class);
|
|
|
|
|
MockableTextToSpeechService.setMocker(delegate);
|
|
|
|
|
|
|
|
|
|
// Test1: Simple end to end test.
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(
|
|
|
|
|
Mockito.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(
|
|
|
|
|
Mockito.verify(delegate, Mockito.times(1)).onIsLanguageAvailable(
|
|
|
|
|
"eng", "USA", "");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public void testDefaultLanguage_setsVoiceName() throws Exception {
|
|
|
|
|
IDelegate delegate = LittleMock.mock(IDelegate.class);
|
|
|
|
|
IDelegate delegate = Mockito.mock(IDelegate.class);
|
|
|
|
|
MockableTextToSpeechService.setMocker(delegate);
|
|
|
|
|
Locale defaultLocale = Locale.getDefault();
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------
|
|
|
|
|
// Test that default language also sets the default voice
|
|
|
|
|
// name
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).
|
|
|
|
|
when(delegate).onIsLanguageAvailable(
|
|
|
|
|
defaultLocale.getISO3Language(),
|
|
|
|
|
defaultLocale.getISO3Country().toUpperCase(),
|
|
|
|
|
defaultLocale.getVariant());
|
|
|
|
|
LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).
|
|
|
|
|
Mockito.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).
|
|
|
|
|
when(delegate).onLoadLanguage(
|
|
|
|
|
defaultLocale.getISO3Language(),
|
|
|
|
|
defaultLocale.getISO3Country(),
|
|
|
|
|
defaultLocale.getVariant());
|
|
|
|
|
|
|
|
|
|
blockingCallSpeak("foo bar", delegate);
|
|
|
|
|
ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor();
|
|
|
|
|
LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(),
|
|
|
|
|
LittleMock.<SynthesisCallback>anyObject());
|
|
|
|
|
ArgumentCaptor<SynthesisRequest> req = ArgumentCaptor.forClass(SynthesisRequest.class);
|
|
|
|
|
Mockito.verify(delegate, Mockito.times(1)).onSynthesizeText(req.capture(),
|
|
|
|
|
Mockito.<SynthesisCallback>anyObject());
|
|
|
|
|
|
|
|
|
|
assertEquals(defaultLocale.getISO3Language(), req.getValue().getLanguage());
|
|
|
|
|
assertEquals(defaultLocale.getISO3Country(), req.getValue().getCountry());
|
|
|
|
|
@@ -185,8 +188,8 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
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());
|
|
|
|
|
doCountDown(latch).when(mock).onSynthesizeText(Mockito.<SynthesisRequest>anyObject(),
|
|
|
|
|
Mockito.<SynthesisCallback>anyObject());
|
|
|
|
|
mTts.speak(speech, TextToSpeech.QUEUE_ADD, null);
|
|
|
|
|
|
|
|
|
|
awaitCountDown(latch, 5, TimeUnit.SECONDS);
|
|
|
|
|
@@ -194,7 +197,7 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
|
|
|
|
|
private void blockingInitAndVerify(final String engine, int errorCode) throws
|
|
|
|
|
InterruptedException {
|
|
|
|
|
TextToSpeech.OnInitListener listener = LittleMock.mock(
|
|
|
|
|
TextToSpeech.OnInitListener listener = Mockito.mock(
|
|
|
|
|
TextToSpeech.OnInitListener.class);
|
|
|
|
|
|
|
|
|
|
final CountDownLatch latch = new CountDownLatch(1);
|
|
|
|
|
@@ -206,18 +209,18 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
awaitCountDown(latch, 5, TimeUnit.SECONDS);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public interface CountDownBehaviour extends Behaviour {
|
|
|
|
|
public static abstract class CountDownBehaviour extends StubberImpl {
|
|
|
|
|
/** Used to mock methods that return a result. */
|
|
|
|
|
Behaviour andReturn(Object result);
|
|
|
|
|
public abstract Stubber 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>() {
|
|
|
|
|
return Mockito.doAnswer(new Answer<Void>() {
|
|
|
|
|
@Override
|
|
|
|
|
public Void call() throws Exception {
|
|
|
|
|
public Void answer(InvocationOnMock invocation) throws Exception {
|
|
|
|
|
latch.countDown();
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
@@ -225,13 +228,13 @@ public class TextToSpeechTests extends InstrumentationTestCase {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Override
|
|
|
|
|
public Behaviour andReturn(final Object result) {
|
|
|
|
|
return new Behaviour() {
|
|
|
|
|
public Stubber andReturn(final Object result) {
|
|
|
|
|
return new StubberImpl() {
|
|
|
|
|
@Override
|
|
|
|
|
public <T> T when(T mock) {
|
|
|
|
|
return LittleMock.doAnswer(new Callable<Object>() {
|
|
|
|
|
return Mockito.doAnswer(new Answer<Object>() {
|
|
|
|
|
@Override
|
|
|
|
|
public Object call() throws Exception {
|
|
|
|
|
public Object answer(InvocationOnMock invocation) throws Exception {
|
|
|
|
|
latch.countDown();
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|