// 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