OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include <queue> | 5 #include <queue> |
6 | 6 |
7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
8 #include "base/message_loop.h" | 8 #include "base/message_loop.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "content/browser/speech/audio_buffer.h" | 10 #include "content/browser/speech/audio_buffer.h" |
(...skipping 20 matching lines...) Expand all Loading... |
31 public: | 31 public: |
32 GoogleStreamingRemoteEngineTest() | 32 GoogleStreamingRemoteEngineTest() |
33 : last_number_of_upstream_chunks_seen_(0U), | 33 : last_number_of_upstream_chunks_seen_(0U), |
34 error_(SPEECH_RECOGNITION_ERROR_NONE) { } | 34 error_(SPEECH_RECOGNITION_ERROR_NONE) { } |
35 | 35 |
36 // Creates a speech recognition request and invokes its URL fetcher delegate | 36 // Creates a speech recognition request and invokes its URL fetcher delegate |
37 // with the given test data. | 37 // with the given test data. |
38 void CreateAndTestRequest(bool success, const std::string& http_response); | 38 void CreateAndTestRequest(bool success, const std::string& http_response); |
39 | 39 |
40 // SpeechRecognitionRequestDelegate methods. | 40 // SpeechRecognitionRequestDelegate methods. |
41 virtual void OnSpeechRecognitionEngineResults( | 41 virtual void OnSpeechRecognitionEngineResult( |
42 const SpeechRecognitionResults& results) OVERRIDE { | 42 const SpeechRecognitionResult& result) OVERRIDE { |
43 results_.push(results); | 43 results_.push(result); |
44 } | 44 } |
45 virtual void OnSpeechRecognitionEngineError( | 45 virtual void OnSpeechRecognitionEngineError( |
46 const SpeechRecognitionError& error) OVERRIDE { | 46 const SpeechRecognitionError& error) OVERRIDE { |
47 error_ = error.code; | 47 error_ = error.code; |
48 } | 48 } |
49 | 49 |
50 // testing::Test methods. | 50 // testing::Test methods. |
51 virtual void SetUp() OVERRIDE; | 51 virtual void SetUp() OVERRIDE; |
52 virtual void TearDown() OVERRIDE; | 52 virtual void TearDown() OVERRIDE; |
53 | 53 |
54 protected: | 54 protected: |
55 enum DownstreamError { | 55 enum DownstreamError { |
56 DOWNSTREAM_ERROR_NONE, | 56 DOWNSTREAM_ERROR_NONE, |
57 DOWNSTREAM_ERROR_HTTP500, | 57 DOWNSTREAM_ERROR_HTTP500, |
58 DOWNSTREAM_ERROR_NETWORK, | 58 DOWNSTREAM_ERROR_NETWORK, |
59 DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH | 59 DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH |
60 }; | 60 }; |
61 static bool ResultsAreEqual(const SpeechRecognitionResults& a, | 61 static bool ResultsAreEqual(const SpeechRecognitionResult& a, |
62 const SpeechRecognitionResults& b); | 62 const SpeechRecognitionResult& b); |
63 static std::string SerializeProtobufResponse( | 63 static std::string SerializeProtobufResponse( |
64 const proto::SpeechRecognitionEvent& msg); | 64 const proto::SpeechRecognitionEvent& msg); |
65 static std::string ToBigEndian32(uint32 value); | 65 static std::string ToBigEndian32(uint32 value); |
66 | 66 |
67 TestURLFetcher* GetUpstreamFetcher(); | 67 TestURLFetcher* GetUpstreamFetcher(); |
68 TestURLFetcher* GetDownstreamFetcher(); | 68 TestURLFetcher* GetDownstreamFetcher(); |
69 void StartMockRecognition(); | 69 void StartMockRecognition(); |
70 void EndMockRecognition(); | 70 void EndMockRecognition(); |
71 void InjectDummyAudioChunk(); | 71 void InjectDummyAudioChunk(); |
72 size_t UpstreamChunksUploadedFromLastCall(); | 72 size_t UpstreamChunksUploadedFromLastCall(); |
73 void ProvideMockProtoResultDownstream( | 73 void ProvideMockProtoResultDownstream( |
74 const proto::SpeechRecognitionEvent& result); | 74 const proto::SpeechRecognitionEvent& result); |
75 void ProvideMockResultDownstream(const SpeechRecognitionResult& result); | 75 void ProvideMockResultDownstream(const SpeechRecognitionResult& result); |
76 void ExpectResultsReceived(const SpeechRecognitionResults& result); | 76 void ExpectResultReceived(const SpeechRecognitionResult& result); |
77 void CloseMockDownstream(DownstreamError error); | 77 void CloseMockDownstream(DownstreamError error); |
78 | 78 |
79 scoped_ptr<GoogleStreamingRemoteEngine> engine_under_test_; | 79 scoped_ptr<GoogleStreamingRemoteEngine> engine_under_test_; |
80 TestURLFetcherFactory url_fetcher_factory_; | 80 TestURLFetcherFactory url_fetcher_factory_; |
81 size_t last_number_of_upstream_chunks_seen_; | 81 size_t last_number_of_upstream_chunks_seen_; |
82 MessageLoop message_loop_; | 82 MessageLoop message_loop_; |
83 std::string response_buffer_; | 83 std::string response_buffer_; |
84 SpeechRecognitionErrorCode error_; | 84 SpeechRecognitionErrorCode error_; |
85 std::queue<SpeechRecognitionResults> results_; | 85 std::queue<SpeechRecognitionResult> results_; |
86 }; | 86 }; |
87 | 87 |
88 TEST_F(GoogleStreamingRemoteEngineTest, SingleDefinitiveResult) { | 88 TEST_F(GoogleStreamingRemoteEngineTest, SingleDefinitiveResult) { |
89 StartMockRecognition(); | 89 StartMockRecognition(); |
90 ASSERT_TRUE(GetUpstreamFetcher()); | 90 ASSERT_TRUE(GetUpstreamFetcher()); |
91 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 91 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
92 | 92 |
93 // Inject some dummy audio chunks and check a corresponding chunked upload | 93 // Inject some dummy audio chunks and check a corresponding chunked upload |
94 // is performed every time on the server. | 94 // is performed every time on the server. |
95 for (int i = 0; i < 3; ++i) { | 95 for (int i = 0; i < 3; ++i) { |
96 InjectDummyAudioChunk(); | 96 InjectDummyAudioChunk(); |
97 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 97 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
98 } | 98 } |
99 | 99 |
100 // Ensure that a final (empty) audio chunk is uploaded on chunks end. | 100 // Ensure that a final (empty) audio chunk is uploaded on chunks end. |
101 engine_under_test_->AudioChunksEnded(); | 101 engine_under_test_->AudioChunksEnded(); |
102 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 102 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
103 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 103 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
104 | 104 |
105 // Simulate a protobuf message streamed from the server containing a single | 105 // Simulate a protobuf message streamed from the server containing a single |
106 // result with two hypotheses. | 106 // result with two hypotheses. |
107 SpeechRecognitionResults results; | 107 SpeechRecognitionResult result; |
108 results.push_back(SpeechRecognitionResult()); | |
109 SpeechRecognitionResult& result = results.back(); | |
110 result.is_provisional = false; | 108 result.is_provisional = false; |
111 result.hypotheses.push_back( | 109 result.hypotheses.push_back( |
112 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 1"), 0.1F)); | 110 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 1"), 0.1F)); |
113 result.hypotheses.push_back( | 111 result.hypotheses.push_back( |
114 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 2"), 0.2F)); | 112 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis 2"), 0.2F)); |
115 | 113 |
116 ProvideMockResultDownstream(result); | 114 ProvideMockResultDownstream(result); |
117 ExpectResultsReceived(results); | 115 ExpectResultReceived(result); |
118 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 116 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
119 | 117 |
120 // Ensure everything is closed cleanly after the downstream is closed. | 118 // Ensure everything is closed cleanly after the downstream is closed. |
121 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 119 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
122 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 120 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
123 EndMockRecognition(); | 121 EndMockRecognition(); |
124 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 122 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
125 ASSERT_EQ(0U, results_.size()); | 123 ASSERT_EQ(0U, results_.size()); |
126 } | 124 } |
127 | 125 |
128 TEST_F(GoogleStreamingRemoteEngineTest, SeveralStreamingResults) { | 126 TEST_F(GoogleStreamingRemoteEngineTest, SeveralStreamingResults) { |
129 StartMockRecognition(); | 127 StartMockRecognition(); |
130 ASSERT_TRUE(GetUpstreamFetcher()); | 128 ASSERT_TRUE(GetUpstreamFetcher()); |
131 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 129 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
132 | 130 |
133 for (int i = 0; i < 4; ++i) { | 131 for (int i = 0; i < 4; ++i) { |
134 InjectDummyAudioChunk(); | 132 InjectDummyAudioChunk(); |
135 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 133 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
136 | 134 |
137 SpeechRecognitionResults results; | 135 SpeechRecognitionResult result; |
138 results.push_back(SpeechRecognitionResult()); | |
139 SpeechRecognitionResult& result = results.back(); | |
140 result.is_provisional = (i % 2 == 0); // Alternate result types. | 136 result.is_provisional = (i % 2 == 0); // Alternate result types. |
141 float confidence = result.is_provisional ? 0.0F : (i * 0.1F); | 137 float confidence = result.is_provisional ? 0.0F : (i * 0.1F); |
142 result.hypotheses.push_back( | 138 result.hypotheses.push_back( |
143 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), confidence)); | 139 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), confidence)); |
144 | 140 |
145 ProvideMockResultDownstream(result); | 141 ProvideMockResultDownstream(result); |
146 ExpectResultsReceived(results); | 142 ExpectResultReceived(result); |
147 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 143 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
148 } | 144 } |
149 | 145 |
150 // Ensure that a final (empty) audio chunk is uploaded on chunks end. | 146 // Ensure that a final (empty) audio chunk is uploaded on chunks end. |
151 engine_under_test_->AudioChunksEnded(); | 147 engine_under_test_->AudioChunksEnded(); |
152 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 148 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
153 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 149 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
154 | 150 |
155 // Simulate a final definitive result. | 151 // Simulate a final definitive result. |
156 SpeechRecognitionResults results; | 152 SpeechRecognitionResult result; |
157 results.push_back(SpeechRecognitionResult()); | |
158 SpeechRecognitionResult& result = results.back(); | |
159 result.is_provisional = false; | 153 result.is_provisional = false; |
160 result.hypotheses.push_back( | 154 result.hypotheses.push_back( |
161 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 1.0F)); | 155 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 1.0F)); |
162 ProvideMockResultDownstream(result); | 156 ProvideMockResultDownstream(result); |
163 ExpectResultsReceived(results); | 157 ExpectResultReceived(result); |
164 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 158 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
165 | 159 |
166 // Ensure everything is closed cleanly after the downstream is closed. | 160 // Ensure everything is closed cleanly after the downstream is closed. |
167 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 161 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
168 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 162 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
169 EndMockRecognition(); | 163 EndMockRecognition(); |
170 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 164 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
171 ASSERT_EQ(0U, results_.size()); | 165 ASSERT_EQ(0U, results_.size()); |
172 } | 166 } |
173 | 167 |
174 TEST_F(GoogleStreamingRemoteEngineTest, NoFinalResultAfterAudioChunksEnded) { | 168 TEST_F(GoogleStreamingRemoteEngineTest, NoFinalResultAfterAudioChunksEnded) { |
175 StartMockRecognition(); | 169 StartMockRecognition(); |
176 ASSERT_TRUE(GetUpstreamFetcher()); | 170 ASSERT_TRUE(GetUpstreamFetcher()); |
177 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 171 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
178 | 172 |
179 // Simulate one pushed audio chunk. | 173 // Simulate one pushed audio chunk. |
180 InjectDummyAudioChunk(); | 174 InjectDummyAudioChunk(); |
181 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 175 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
182 | 176 |
183 // Simulate the corresponding definitive result. | 177 // Simulate the corresponding definitive result. |
184 SpeechRecognitionResults results; | 178 SpeechRecognitionResult result; |
185 results.push_back(SpeechRecognitionResult()); | |
186 SpeechRecognitionResult& result = results.back(); | |
187 result.hypotheses.push_back( | 179 result.hypotheses.push_back( |
188 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), 1.0F)); | 180 SpeechRecognitionHypothesis(UTF8ToUTF16("hypothesis"), 1.0F)); |
189 ProvideMockResultDownstream(result); | 181 ProvideMockResultDownstream(result); |
190 ExpectResultsReceived(results); | 182 ExpectResultReceived(result); |
191 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 183 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
192 | 184 |
193 // Simulate a silent downstream closure after |AudioChunksEnded|. | 185 // Simulate a silent downstream closure after |AudioChunksEnded|. |
194 engine_under_test_->AudioChunksEnded(); | 186 engine_under_test_->AudioChunksEnded(); |
195 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 187 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
196 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 188 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
197 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 189 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
198 | 190 |
199 // Expect an empty result, aimed at notifying recognition ended with no | 191 // Expect an empty result, aimed at notifying recognition ended with no |
200 // actual results nor errors. | 192 // actual results nor errors. |
201 SpeechRecognitionResults empty_results; | 193 SpeechRecognitionResult empty_result; |
202 ExpectResultsReceived(empty_results); | 194 ExpectResultReceived(empty_result); |
203 | 195 |
204 // Ensure everything is closed cleanly after the downstream is closed. | 196 // Ensure everything is closed cleanly after the downstream is closed. |
205 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 197 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
206 EndMockRecognition(); | 198 EndMockRecognition(); |
207 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 199 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
208 ASSERT_EQ(0U, results_.size()); | 200 ASSERT_EQ(0U, results_.size()); |
209 } | 201 } |
210 | 202 |
211 TEST_F(GoogleStreamingRemoteEngineTest, NoMatchError) { | 203 TEST_F(GoogleStreamingRemoteEngineTest, NoMatchError) { |
212 StartMockRecognition(); | 204 StartMockRecognition(); |
213 ASSERT_TRUE(GetUpstreamFetcher()); | 205 ASSERT_TRUE(GetUpstreamFetcher()); |
214 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 206 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
215 | 207 |
216 for (int i = 0; i < 3; ++i) | 208 for (int i = 0; i < 3; ++i) |
217 InjectDummyAudioChunk(); | 209 InjectDummyAudioChunk(); |
218 engine_under_test_->AudioChunksEnded(); | 210 engine_under_test_->AudioChunksEnded(); |
219 ASSERT_EQ(4U, UpstreamChunksUploadedFromLastCall()); | 211 ASSERT_EQ(4U, UpstreamChunksUploadedFromLastCall()); |
220 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 212 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
221 | 213 |
222 // Simulate only a provisional result. | 214 // Simulate only a provisional result. |
223 SpeechRecognitionResults results; | 215 SpeechRecognitionResult result; |
224 results.push_back(SpeechRecognitionResult()); | |
225 SpeechRecognitionResult& result = results.back(); | |
226 result.is_provisional = true; | 216 result.is_provisional = true; |
227 result.hypotheses.push_back( | 217 result.hypotheses.push_back( |
228 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 0.0F)); | 218 SpeechRecognitionHypothesis(UTF8ToUTF16("The final result"), 0.0F)); |
229 ProvideMockResultDownstream(result); | 219 ProvideMockResultDownstream(result); |
230 ExpectResultsReceived(results); | 220 ExpectResultReceived(result); |
231 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 221 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
232 | 222 |
233 CloseMockDownstream(DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH); | 223 CloseMockDownstream(DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH); |
234 | 224 |
235 // Expect an empty result. | 225 // Expect an empty result. |
236 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 226 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
237 EndMockRecognition(); | 227 EndMockRecognition(); |
238 SpeechRecognitionResults empty_result; | 228 SpeechRecognitionResult empty_result; |
239 ExpectResultsReceived(empty_result); | 229 ExpectResultReceived(empty_result); |
240 } | 230 } |
241 | 231 |
242 TEST_F(GoogleStreamingRemoteEngineTest, HTTPError) { | 232 TEST_F(GoogleStreamingRemoteEngineTest, HTTPError) { |
243 StartMockRecognition(); | 233 StartMockRecognition(); |
244 ASSERT_TRUE(GetUpstreamFetcher()); | 234 ASSERT_TRUE(GetUpstreamFetcher()); |
245 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); | 235 ASSERT_EQ(0U, UpstreamChunksUploadedFromLastCall()); |
246 | 236 |
247 InjectDummyAudioChunk(); | 237 InjectDummyAudioChunk(); |
248 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); | 238 ASSERT_EQ(1U, UpstreamChunksUploadedFromLastCall()); |
249 | 239 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 proto::SpeechRecognitionEvent proto_event; | 280 proto::SpeechRecognitionEvent proto_event; |
291 proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS); | 281 proto_event.set_status(proto::SpeechRecognitionEvent::STATUS_SUCCESS); |
292 proto::SpeechRecognitionResult* proto_result = proto_event.add_result(); | 282 proto::SpeechRecognitionResult* proto_result = proto_event.add_result(); |
293 proto_result->set_stability(0.5); | 283 proto_result->set_stability(0.5); |
294 proto::SpeechRecognitionAlternative *proto_alternative = | 284 proto::SpeechRecognitionAlternative *proto_alternative = |
295 proto_result->add_alternative(); | 285 proto_result->add_alternative(); |
296 proto_alternative->set_transcript("foo"); | 286 proto_alternative->set_transcript("foo"); |
297 ProvideMockProtoResultDownstream(proto_event); | 287 ProvideMockProtoResultDownstream(proto_event); |
298 | 288 |
299 // Set up expectations. | 289 // Set up expectations. |
300 SpeechRecognitionResults results; | 290 SpeechRecognitionResult expected; |
301 results.push_back(SpeechRecognitionResult()); | 291 expected.is_provisional = true; |
302 SpeechRecognitionResult& result = results.back(); | 292 expected.hypotheses.push_back( |
303 result.is_provisional = true; | |
304 result.hypotheses.push_back( | |
305 SpeechRecognitionHypothesis(UTF8ToUTF16("foo"), 0.5)); | 293 SpeechRecognitionHypothesis(UTF8ToUTF16("foo"), 0.5)); |
306 | 294 |
307 // Check that the protobuf generated the expected result. | 295 // Check that the protobuf generated the expected result. |
308 ExpectResultsReceived(results); | 296 ExpectResultReceived(expected); |
309 | 297 |
310 // Since it was a provisional result, recognition is still pending. | 298 // Since it was a provisional result, recognition is still pending. |
311 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); | 299 ASSERT_TRUE(engine_under_test_->IsRecognitionPending()); |
312 | 300 |
313 // Shut down. | 301 // Shut down. |
314 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); | 302 CloseMockDownstream(DOWNSTREAM_ERROR_NONE); |
315 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); | 303 ASSERT_FALSE(engine_under_test_->IsRecognitionPending()); |
316 EndMockRecognition(); | 304 EndMockRecognition(); |
317 | 305 |
318 // Since there was no final result, we get an empty "no match" result. | 306 // Since there was no final result, we get an empty "no match" result. |
319 SpeechRecognitionResults empty_result; | 307 SpeechRecognitionResult empty_result; |
320 ExpectResultsReceived(empty_result); | 308 ExpectResultReceived(empty_result); |
321 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); | 309 ASSERT_EQ(SPEECH_RECOGNITION_ERROR_NONE, error_); |
322 ASSERT_EQ(0U, results_.size()); | 310 ASSERT_EQ(0U, results_.size()); |
323 } | 311 } |
324 | 312 |
325 void GoogleStreamingRemoteEngineTest::SetUp() { | 313 void GoogleStreamingRemoteEngineTest::SetUp() { |
326 engine_under_test_.reset( | 314 engine_under_test_.reset( |
327 new GoogleStreamingRemoteEngine(NULL /*URLRequestContextGetter*/)); | 315 new GoogleStreamingRemoteEngine(NULL /*URLRequestContextGetter*/)); |
328 engine_under_test_->set_delegate(this); | 316 engine_under_test_->set_delegate(this); |
329 } | 317 } |
330 | 318 |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 | 429 |
442 if (error == DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH) { | 430 if (error == DOWNSTREAM_ERROR_WEBSERVICE_NO_MATCH) { |
443 // Send empty response. | 431 // Send empty response. |
444 proto::SpeechRecognitionEvent response; | 432 proto::SpeechRecognitionEvent response; |
445 response_buffer_.append(SerializeProtobufResponse(response)); | 433 response_buffer_.append(SerializeProtobufResponse(response)); |
446 } | 434 } |
447 downstream_fetcher->SetResponseString(response_buffer_); | 435 downstream_fetcher->SetResponseString(response_buffer_); |
448 downstream_fetcher->delegate()->OnURLFetchComplete(downstream_fetcher); | 436 downstream_fetcher->delegate()->OnURLFetchComplete(downstream_fetcher); |
449 } | 437 } |
450 | 438 |
451 void GoogleStreamingRemoteEngineTest::ExpectResultsReceived( | 439 void GoogleStreamingRemoteEngineTest::ExpectResultReceived( |
452 const SpeechRecognitionResults& results) { | 440 const SpeechRecognitionResult& result) { |
453 ASSERT_GE(1U, results_.size()); | 441 ASSERT_GE(1U, results_.size()); |
454 ASSERT_TRUE(ResultsAreEqual(results, results_.front())); | 442 ASSERT_TRUE(ResultsAreEqual(result, results_.front())); |
455 results_.pop(); | 443 results_.pop(); |
456 } | 444 } |
457 | 445 |
458 bool GoogleStreamingRemoteEngineTest::ResultsAreEqual( | 446 bool GoogleStreamingRemoteEngineTest::ResultsAreEqual( |
459 const SpeechRecognitionResults& a, const SpeechRecognitionResults& b) { | 447 const SpeechRecognitionResult& a, const SpeechRecognitionResult& b) { |
460 if (a.size() != b.size()) | 448 if (a.is_provisional != b.is_provisional || |
| 449 a.hypotheses.size() != b.hypotheses.size()) { |
461 return false; | 450 return false; |
462 | 451 } |
463 SpeechRecognitionResults::const_iterator it_a = a.begin(); | 452 for (size_t i = 0; i < a.hypotheses.size(); ++i) { |
464 SpeechRecognitionResults::const_iterator it_b = b.begin(); | 453 const SpeechRecognitionHypothesis& hyp_a = a.hypotheses[i]; |
465 for (; it_a != a.end() && it_b != b.end(); ++it_a, ++it_b) { | 454 const SpeechRecognitionHypothesis& hyp_b = b.hypotheses[i]; |
466 if (it_a->is_provisional != it_b->is_provisional || | 455 if (hyp_a.utterance != hyp_b.utterance || |
467 it_a->hypotheses.size() != it_b->hypotheses.size()) { | 456 hyp_a.confidence != hyp_b.confidence) { |
468 return false; | 457 return false; |
469 } | 458 } |
470 for (size_t i = 0; i < it_a->hypotheses.size(); ++i) { | |
471 const SpeechRecognitionHypothesis& hyp_a = it_a->hypotheses[i]; | |
472 const SpeechRecognitionHypothesis& hyp_b = it_b->hypotheses[i]; | |
473 if (hyp_a.utterance != hyp_b.utterance || | |
474 hyp_a.confidence != hyp_b.confidence) { | |
475 return false; | |
476 } | |
477 } | |
478 } | 459 } |
479 | |
480 return true; | 460 return true; |
481 } | 461 } |
482 | 462 |
483 std::string GoogleStreamingRemoteEngineTest::SerializeProtobufResponse( | 463 std::string GoogleStreamingRemoteEngineTest::SerializeProtobufResponse( |
484 const proto::SpeechRecognitionEvent& msg) { | 464 const proto::SpeechRecognitionEvent& msg) { |
485 std::string msg_string; | 465 std::string msg_string; |
486 msg.SerializeToString(&msg_string); | 466 msg.SerializeToString(&msg_string); |
487 | 467 |
488 // Prepend 4 byte prefix length indication to the protobuf message as | 468 // Prepend 4 byte prefix length indication to the protobuf message as |
489 // envisaged by the google streaming recognition webservice protocol. | 469 // envisaged by the google streaming recognition webservice protocol. |
490 msg_string.insert(0, ToBigEndian32(msg_string.size())); | 470 msg_string.insert(0, ToBigEndian32(msg_string.size())); |
491 return msg_string; | 471 return msg_string; |
492 } | 472 } |
493 | 473 |
494 std::string GoogleStreamingRemoteEngineTest::ToBigEndian32(uint32 value) { | 474 std::string GoogleStreamingRemoteEngineTest::ToBigEndian32(uint32 value) { |
495 char raw_data[4]; | 475 char raw_data[4]; |
496 raw_data[0] = static_cast<uint8>((value >> 24) & 0xFF); | 476 raw_data[0] = static_cast<uint8>((value >> 24) & 0xFF); |
497 raw_data[1] = static_cast<uint8>((value >> 16) & 0xFF); | 477 raw_data[1] = static_cast<uint8>((value >> 16) & 0xFF); |
498 raw_data[2] = static_cast<uint8>((value >> 8) & 0xFF); | 478 raw_data[2] = static_cast<uint8>((value >> 8) & 0xFF); |
499 raw_data[3] = static_cast<uint8>(value & 0xFF); | 479 raw_data[3] = static_cast<uint8>(value & 0xFF); |
500 return std::string(raw_data, sizeof(raw_data)); | 480 return std::string(raw_data, sizeof(raw_data)); |
501 } | 481 } |
502 | 482 |
503 } // namespace content | 483 } // namespace content |
OLD | NEW |