| // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| #include "base/command_line.h" |
| #include "chrome/browser/extensions/extension_apitest.h" |
| #include "chrome/browser/extensions/extension_tts_api.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| |
| // Needed for CreateFunctor. |
| #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING |
| #include "testing/gmock_mutant.h" |
| |
| #if defined(OS_CHROMEOS) |
| #include "chrome/browser/chromeos/cros/cros_mock.h" |
| #endif |
| |
| using ::testing::AnyNumber; |
| using ::testing::CreateFunctor; |
| using ::testing::DoAll; |
| using ::testing::InSequence; |
| using ::testing::InvokeWithoutArgs; |
| using ::testing::Return; |
| using ::testing::StrictMock; |
| using ::testing::_; |
| |
| class MockExtensionTtsPlatformImpl : public ExtensionTtsPlatformImpl { |
| public: |
| MOCK_METHOD6(Speak, |
| bool(const std::string& utterance, |
| const std::string& locale, |
| const std::string& gender, |
| double rate, |
| double pitch, |
| double volume)); |
| MOCK_METHOD0(StopSpeaking, bool(void)); |
| MOCK_METHOD0(IsSpeaking, bool(void)); |
| |
| void SetErrorToEpicFail() { |
| set_error("epic fail"); |
| } |
| }; |
| |
| class TtsApiTest : public ExtensionApiTest { |
| public: |
| virtual void SetUpCommandLine(CommandLine* command_line) { |
| ExtensionApiTest::SetUpCommandLine(command_line); |
| command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); |
| } |
| |
| virtual void SetUpInProcessBrowserTestFixture() { |
| ExtensionApiTest::SetUpInProcessBrowserTestFixture(); |
| ExtensionTtsController::GetInstance()->SetPlatformImpl( |
| &mock_platform_impl_); |
| } |
| |
| protected: |
| StrictMock<MockExtensionTtsPlatformImpl> mock_platform_impl_; |
| }; |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakFinishesImmediately) { |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/speak_once")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakKeepsSpeakingTwice) { |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/speak_once")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakInterrupt) { |
| // One utterances starts speaking, and then a second interrupts. |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| |
| // Ensure that the first utterance keeps going until it's interrupted. |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .Times(AnyNumber()) |
| .WillRepeatedly(Return(true)); |
| |
| // Expect the second utterance and allow it to continue for two calls to |
| // IsSpeaking and then finish successfully. |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 2", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/interrupt")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakQueueInterrupt) { |
| // In this test, two utterances are queued, and then a third |
| // interrupts. Speak() never gets called on the second utterance. |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| |
| // Ensure that the first utterance keeps going until it's interrupted. |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .Times(AnyNumber()) |
| .WillRepeatedly(Return(true)); |
| |
| // Expect the third utterance and allow it to continue for two calls to |
| // IsSpeaking and then finish successfully. |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 3", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/queue_interrupt")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakEnqueue) { |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 1", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(mock_platform_impl_, Speak("text 2", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(true)) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/enqueue")) << message_; |
| } |
| |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, PlatformSpeakError) { |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(false)); |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) |
| .WillOnce(DoAll( |
| InvokeWithoutArgs( |
| CreateFunctor(&mock_platform_impl_, |
| &MockExtensionTtsPlatformImpl::SetErrorToEpicFail)), |
| Return(false))); |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak(_, _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillOnce(Return(false)); |
| ASSERT_TRUE(RunExtensionTest("tts/speak_error")) << message_; |
| } |
| |
| #if defined(OS_WIN) |
| // Flakily fails on Windows: http://crbug.com/70198 |
| #define MAYBE_Provide FLAKY_Provide |
| #else |
| #define MAYBE_Provide Provide |
| #endif |
| IN_PROC_BROWSER_TEST_F(TtsApiTest, MAYBE_Provide) { |
| EXPECT_CALL(mock_platform_impl_, StopSpeaking()) |
| .WillRepeatedly(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, IsSpeaking()) |
| .WillRepeatedly(Return(false)); |
| |
| { |
| InSequence s; |
| EXPECT_CALL(mock_platform_impl_, Speak("native speech", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("native speech 2", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| EXPECT_CALL(mock_platform_impl_, Speak("native speech 3", _, _, _, _, _)) |
| .WillOnce(Return(true)); |
| } |
| |
| ASSERT_TRUE(RunExtensionTest("tts/provide")) << message_; |
| } |
| |
| #if defined(OS_CHROMEOS) |
| IN_PROC_BROWSER_TEST_F(ExtensionApiTest, TtsChromeOs) { |
| CommandLine::ForCurrentProcess()->AppendSwitch( |
| switches::kEnableExperimentalExtensionApis); |
| |
| chromeos::CrosMock crosMock; |
| crosMock.InitMockSpeechSynthesisLibrary(); |
| crosMock.SetSpeechSynthesisLibraryExpectations(); |
| |
| ASSERT_TRUE(RunExtensionTest("tts/chromeos")) << message_; |
| } |
| #endif |