1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 #include "base/command_line.h" 5 #include "chrome/browser/extensions/extension_apitest.h" 6 #include "chrome/browser/extensions/extension_tts_api.h" 7 #include "chrome/common/chrome_switches.h" 8 #include "testing/gmock/include/gmock/gmock.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 // Needed for CreateFunctor. 12 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING 13 #include "testing/gmock_mutant.h" 14 15 #if defined(OS_CHROMEOS) 16 #include "chrome/browser/chromeos/cros/cros_mock.h" 17 #endif 18 19 using ::testing::AnyNumber; 20 using ::testing::CreateFunctor; 21 using ::testing::DoAll; 22 using ::testing::InSequence; 23 using ::testing::InvokeWithoutArgs; 24 using ::testing::Return; 25 using ::testing::StrictMock; 26 using ::testing::_; 27 28 class MockExtensionTtsPlatformImpl : public ExtensionTtsPlatformImpl { 29 public: 30 MOCK_METHOD6(Speak, 31 bool(const std::string& utterance, 32 const std::string& locale, 33 const std::string& gender, 34 double rate, 35 double pitch, 36 double volume)); 37 MOCK_METHOD0(StopSpeaking, bool(void)); 38 MOCK_METHOD0(IsSpeaking, bool(void)); 39 40 void SetErrorToEpicFail() { 41 set_error("epic fail"); 42 } 43 }; 44 45 class TtsApiTest : public ExtensionApiTest { 46 public: 47 virtual void SetUpCommandLine(CommandLine* command_line) { 48 ExtensionApiTest::SetUpCommandLine(command_line); 49 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); 50 } 51 52 virtual void SetUpInProcessBrowserTestFixture() { 53 ExtensionApiTest::SetUpInProcessBrowserTestFixture(); 54 ExtensionTtsController::GetInstance()->SetPlatformImpl( 55 &mock_platform_impl_); 56 } 57 58 protected: 59 StrictMock<MockExtensionTtsPlatformImpl> mock_platform_impl_; 60 }; 61 62 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakFinishesImmediately) { 63 InSequence s; 64 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 65 .WillOnce(Return(true)); 66 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) 67 .WillOnce(Return(true)); 68 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 69 .WillOnce(Return(false)); 70 ASSERT_TRUE(RunExtensionTest("tts/speak_once")) << message_; 71 } 72 73 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakKeepsSpeakingTwice) { 74 InSequence s; 75 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 76 .WillOnce(Return(true)); 77 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) 78 .WillOnce(Return(true)); 79 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 80 .WillOnce(Return(true)) 81 .WillOnce(Return(true)) 82 .WillOnce(Return(false)); 83 ASSERT_TRUE(RunExtensionTest("tts/speak_once")) << message_; 84 } 85 86 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakInterrupt) { 87 // One utterances starts speaking, and then a second interrupts. 88 InSequence s; 89 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 90 .WillOnce(Return(true)); 91 EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) 92 .WillOnce(Return(true)); 93 94 // Ensure that the first utterance keeps going until it's interrupted. 95 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 96 .Times(AnyNumber()) 97 .WillRepeatedly(Return(true)); 98 99 // Expect the second utterance and allow it to continue for two calls to 100 // IsSpeaking and then finish successfully. 101 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 102 .WillOnce(Return(true)); 103 EXPECT_CALL(mock_platform_impl_, Speak("text 2", _, _, _, _, _)) 104 .WillOnce(Return(true)); 105 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 106 .WillOnce(Return(true)) 107 .WillOnce(Return(true)) 108 .WillOnce(Return(false)); 109 ASSERT_TRUE(RunExtensionTest("tts/interrupt")) << message_; 110 } 111 112 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakQueueInterrupt) { 113 // In this test, two utterances are queued, and then a third 114 // interrupts. Speak() never gets called on the second utterance. 115 InSequence s; 116 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 117 .WillOnce(Return(true)); 118 EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) 119 .WillOnce(Return(true)); 120 121 // Ensure that the first utterance keeps going until it's interrupted. 122 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 123 .Times(AnyNumber()) 124 .WillRepeatedly(Return(true)); 125 126 // Expect the third utterance and allow it to continue for two calls to 127 // IsSpeaking and then finish successfully. 128 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 129 .WillOnce(Return(true)); 130 EXPECT_CALL(mock_platform_impl_, Speak("text 3", _, _, _, _, _)) 131 .WillOnce(Return(true)); 132 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 133 .WillOnce(Return(true)) 134 .WillOnce(Return(true)) 135 .WillOnce(Return(false)); 136 ASSERT_TRUE(RunExtensionTest("tts/queue_interrupt")) << message_; 137 } 138 139 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakEnqueue) { 140 InSequence s; 141 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 142 .WillOnce(Return(true)); 143 EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) 144 .WillOnce(Return(true)); 145 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 146 .WillOnce(Return(true)) 147 .WillOnce(Return(true)) 148 .WillOnce(Return(false)); 149 EXPECT_CALL(mock_platform_impl_, Speak("text 2", _, _, _, _, _)) 150 .WillOnce(Return(true)); 151 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 152 .WillOnce(Return(true)) 153 .WillOnce(Return(true)) 154 .WillOnce(Return(false)); 155 ASSERT_TRUE(RunExtensionTest("tts/enqueue")) << message_; 156 } 157 158 IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) { 159 InSequence s; 160 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 161 .WillOnce(Return(true)); 162 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) 163 .WillOnce(Return(true)); 164 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 165 .WillOnce(Return(false)); 166 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 167 .WillOnce(Return(true)); 168 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) 169 .WillOnce(DoAll( 170 InvokeWithoutArgs( 171 CreateFunctor(&mock_platform_impl_, 172 &MockExtensionTtsPlatformImpl::SetErrorToEpicFail)), 173 Return(false))); 174 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 175 .WillOnce(Return(true)); 176 EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) 177 .WillOnce(Return(true)); 178 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 179 .WillOnce(Return(false)); 180 ASSERT_TRUE(RunExtensionTest("tts/speak_error")) << message_; 181 } 182 183 #if defined(OS_WIN) 184 // Flakily fails on Windows: http://crbug.com/70198 185 #define MAYBE_Provide FLAKY_Provide 186 #else 187 #define MAYBE_Provide Provide 188 #endif 189 IN_PROC_BROWSER_TEST_F(TtsApiTest, MAYBE_Provide) { 190 EXPECT_CALL(mock_platform_impl_, StopSpeaking()) 191 .WillRepeatedly(Return(true)); 192 EXPECT_CALL(mock_platform_impl_, IsSpeaking()) 193 .WillRepeatedly(Return(false)); 194 195 { 196 InSequence s; 197 EXPECT_CALL(mock_platform_impl_, Speak("native speech", _, _, _, _, _)) 198 .WillOnce(Return(true)); 199 EXPECT_CALL(mock_platform_impl_, Speak("native speech 2", _, _, _, _, _)) 200 .WillOnce(Return(true)); 201 EXPECT_CALL(mock_platform_impl_, Speak("native speech 3", _, _, _, _, _)) 202 .WillOnce(Return(true)); 203 } 204 205 ASSERT_TRUE(RunExtensionTest("tts/provide")) << message_; 206 } 207 208 #if defined(OS_CHROMEOS) 209 IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TtsChromeOs) { 210 CommandLine::ForCurrentProcess()->AppendSwitch( 211 switches::kEnableExperimentalExtensionApis); 212 213 chromeos::CrosMock crosMock; 214 crosMock.InitMockSpeechSynthesisLibrary(); 215 crosMock.SetSpeechSynthesisLibraryExpectations(); 216 217 ASSERT_TRUE(RunExtensionTest("tts/chromeos")) << message_; 218 } 219 #endif 220