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 19using ::testing::AnyNumber; 20using ::testing::CreateFunctor; 21using ::testing::DoAll; 22using ::testing::InSequence; 23using ::testing::InvokeWithoutArgs; 24using ::testing::Return; 25using ::testing::StrictMock; 26using ::testing::_; 27 28class 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 45class 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 62IN_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 73IN_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 86IN_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 112IN_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 139IN_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 158IN_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 189IN_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) 209IN_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