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
SetErrorToEpicFail()40 void SetErrorToEpicFail() {
41 set_error("epic fail");
42 }
43 };
44
45 class TtsApiTest : public ExtensionApiTest {
46 public:
SetUpCommandLine(CommandLine * command_line)47 virtual void SetUpCommandLine(CommandLine* command_line) {
48 ExtensionApiTest::SetUpCommandLine(command_line);
49 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
50 }
51
SetUpInProcessBrowserTestFixture()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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakFinishesImmediately)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakKeepsSpeakingTwice)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakInterrupt)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakQueueInterrupt)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakEnqueue)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,PlatformSpeakError)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
IN_PROC_BROWSER_TEST_F(TtsApiTest,MAYBE_Provide)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)
IN_PROC_BROWSER_TEST_F(ExtensionApiTest,TtsChromeOs)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