1c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath/* 2c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * Copyright (C) 2011 The Android Open Source Project 3c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * 4c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * Licensed under the Apache License, Version 2.0 (the "License"); 5c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * you may not use this file except in compliance with the License. 6c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * You may obtain a copy of the License at 7c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * 8c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * http://www.apache.org/licenses/LICENSE-2.0 9c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * 10c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * Unless required by applicable law or agreed to in writing, software 11c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * distributed under the License is distributed on an "AS IS" BASIS, 12c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * See the License for the specific language governing permissions and 14c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath * limitations under the License. 15c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath */ 16c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 17c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathpackage com.android.speech.tts; 18c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 19c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport android.speech.tts.SynthesisCallback; 20c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport android.speech.tts.SynthesisRequest; 21c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport android.speech.tts.TextToSpeech; 22c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport android.test.InstrumentationTestCase; 23c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 24c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport com.android.speech.tts.MockableTextToSpeechService.IDelegate; 25c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport com.google.testing.littlemock.ArgumentCaptor; 26c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport com.google.testing.littlemock.Behaviour; 27c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport com.google.testing.littlemock.LittleMock; 28c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport junit.framework.Assert; 29c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 30c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport java.util.Locale; 31c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport java.util.concurrent.Callable; 32c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport java.util.concurrent.CountDownLatch; 33c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathimport java.util.concurrent.TimeUnit; 34c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 35c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamathpublic class TextToSpeechTests extends InstrumentationTestCase { 36c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath private static final String MOCK_ENGINE = "com.android.speech.tts"; 37c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath private static final String MOCK_PACKAGE = "com.android.speech.tts.__testpackage__"; 38c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 39c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath private TextToSpeech mTts; 40c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 41c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 42c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void setUp() throws Exception { 43c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath IDelegate passThrough = LittleMock.mock(IDelegate.class); 44c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath MockableTextToSpeechService.setMocker(passThrough); 45c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 46c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath blockingInitAndVerify(MOCK_ENGINE, TextToSpeech.SUCCESS); 47c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals(MOCK_ENGINE, mTts.getCurrentEngine()); 48c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 49c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 50c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 51c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 52c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void tearDown() { 53c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath if (mTts != null) { 54c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts.shutdown(); 55c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 56c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 57c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 58c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void testEngineInitialized() throws Exception { 59c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // Fail on an engine that doesn't exist. 60c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath blockingInitAndVerify("__DOES_NOT_EXIST__", TextToSpeech.ERROR); 61c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 62c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // Also, the "current engine" must be null 63c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertNull(mTts.getCurrentEngine()); 64c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 65c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 66c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void testSetLanguage_delegation() { 67c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath IDelegate delegate = LittleMock.mock(IDelegate.class); 68c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath MockableTextToSpeechService.setMocker(delegate); 69c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 70c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // Test 1 :Tests that calls to onLoadLanguage( ) are delegated through to the 71c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // service without any caching or intermediate steps. 72c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts.setLanguage(new Locale("eng", "USA", "variant")); 7393d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable( 7493d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak "eng", "USA", "variant"); 75c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.verify(delegate, LittleMock.times(1)).onLoadLanguage( 76c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath "eng", "USA", "variant"); 77c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 78c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 79c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void testSetLanguage_availableLanguage() throws Exception { 80c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath IDelegate delegate = LittleMock.mock(IDelegate.class); 81c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath MockableTextToSpeechService.setMocker(delegate); 82c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 83c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // --------------------------------------------------------- 84c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // Test 2 : Tests that when the language is successfully set 85c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // like above (returns LANG_COUNTRY_AVAILABLE). That the 86c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // request language changes from that point on. 8793d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onIsLanguageAvailable( 8893d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak "eng", "USA", "variant"); 89c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when(delegate).onLoadLanguage( 90c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath "eng", "USA", "variant"); 91c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts.setLanguage(new Locale("eng", "USA", "variant")); 92c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath blockingCallSpeak("foo bar", delegate); 93c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath ArgumentCaptor<SynthesisRequest> req = LittleMock.createCaptor(); 94c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req.capture(), 95c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.<SynthesisCallback>anyObject()); 96c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 97c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("eng", req.getValue().getLanguage()); 98c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("USA", req.getValue().getCountry()); 99c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("", req.getValue().getVariant()); 100c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 101c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 102c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void testSetLanguage_unavailableLanguage() throws Exception { 103c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath IDelegate delegate = LittleMock.mock(IDelegate.class); 104c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath MockableTextToSpeechService.setMocker(delegate); 105c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 106c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // --------------------------------------------------------- 107c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // TEST 3 : Tests that the language that is set does not change when the 108c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // engine reports it could not load the specified language. 109c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when( 11093d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak delegate).onIsLanguageAvailable("fra", "FRA", ""); 11193d34a61dbdfd9ece9ac4a53d78e896638172895Przemyslaw Szczepaniak LittleMock.doReturn(TextToSpeech.LANG_NOT_SUPPORTED).when( 112c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath delegate).onLoadLanguage("fra", "FRA", ""); 113c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts.setLanguage(Locale.FRANCE); 114c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath blockingCallSpeak("le fou barre", delegate); 115c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath ArgumentCaptor<SynthesisRequest> req2 = LittleMock.createCaptor(); 116c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.verify(delegate, LittleMock.times(1)).onSynthesizeText(req2.capture(), 117c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.<SynthesisCallback>anyObject()); 118c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 119c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // The params are basically unchanged. 120c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("eng", req2.getValue().getLanguage()); 121c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("USA", req2.getValue().getCountry()); 122c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals("", req2.getValue().getVariant()); 123c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 124c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 125c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public void testIsLanguageAvailable() { 126c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath IDelegate delegate = LittleMock.mock(IDelegate.class); 127c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath MockableTextToSpeechService.setMocker(delegate); 128c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 129c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath // Test1: Simple end to end test. 130c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.doReturn(TextToSpeech.LANG_COUNTRY_AVAILABLE).when( 131c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath delegate).onIsLanguageAvailable("eng", "USA", ""); 132c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 133c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath assertEquals(TextToSpeech.LANG_COUNTRY_AVAILABLE, mTts.isLanguageAvailable(Locale.US)); 134c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.verify(delegate, LittleMock.times(1)).onIsLanguageAvailable( 135c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath "eng", "USA", ""); 136c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 137c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 138c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 139c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath private void blockingCallSpeak(String speech, IDelegate mock) throws 140c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath InterruptedException { 141c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath final CountDownLatch latch = new CountDownLatch(1); 142c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath doCountDown(latch).when(mock).onSynthesizeText(LittleMock.<SynthesisRequest>anyObject(), 143c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath LittleMock.<SynthesisCallback>anyObject()); 144c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts.speak(speech, TextToSpeech.QUEUE_ADD, null); 145c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 146c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath awaitCountDown(latch, 5, TimeUnit.SECONDS); 147c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 148c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 149c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath private void blockingInitAndVerify(final String engine, int errorCode) throws 150c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath InterruptedException { 151c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath TextToSpeech.OnInitListener listener = LittleMock.mock( 152c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath TextToSpeech.OnInitListener.class); 153c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 154c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath final CountDownLatch latch = new CountDownLatch(1); 155c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath doCountDown(latch).when(listener).onInit(errorCode); 156c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 157c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath mTts = new TextToSpeech(getInstrumentation().getTargetContext(), 158c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath listener, engine, MOCK_PACKAGE, false /* use fallback package */); 159c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 160c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath awaitCountDown(latch, 5, TimeUnit.SECONDS); 161c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 162c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 163c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public interface CountDownBehaviour extends Behaviour { 164c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath /** Used to mock methods that return a result. */ 165c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath Behaviour andReturn(Object result); 166c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 167c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 168c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public static CountDownBehaviour doCountDown(final CountDownLatch latch) { 169c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return new CountDownBehaviour() { 170c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 171c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public <T> T when(T mock) { 172c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return LittleMock.doAnswer(new Callable<Void>() { 173c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 174c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public Void call() throws Exception { 175c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath latch.countDown(); 176c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return null; 177c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 178c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath }).when(mock); 179c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 180c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 181c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 182c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public Behaviour andReturn(final Object result) { 183c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return new Behaviour() { 184c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 185c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public <T> T when(T mock) { 186c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return LittleMock.doAnswer(new Callable<Object>() { 187c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath @Override 188c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public Object call() throws Exception { 189c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath latch.countDown(); 190c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath return result; 191c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 192c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath }).when(mock); 193c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 194c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath }; 195c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 196c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath }; 197c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 198c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath 199c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath public static void awaitCountDown(CountDownLatch latch, long timeout, TimeUnit unit) 200c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath throws InterruptedException { 201c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath Assert.assertTrue("Waited too long for method call", latch.await(timeout, unit)); 202c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath } 203c60aad2a8ab519a9f9ac03f4f9f929ded7ba2db5Narayan Kamath} 204