Home | History | Annotate | Download | only in speech
      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
      3 // found in the LICENSE file.
      4 
      5 #include "base/message_loop/message_loop.h"
      6 #include "base/strings/utf_string_conversions.h"
      7 #include "content/browser/speech/audio_buffer.h"
      8 #include "content/browser/speech/google_one_shot_remote_engine.h"
      9 #include "content/public/common/speech_recognition_error.h"
     10 #include "content/public/common/speech_recognition_result.h"
     11 #include "net/url_request/test_url_fetcher_factory.h"
     12 #include "net/url_request/url_request_context_getter.h"
     13 #include "net/url_request/url_request_status.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 
     16 namespace content {
     17 
     18 class GoogleOneShotRemoteEngineTest : public SpeechRecognitionEngineDelegate,
     19                                       public testing::Test {
     20  public:
     21   GoogleOneShotRemoteEngineTest()
     22       : error_(SPEECH_RECOGNITION_ERROR_NONE) {}
     23 
     24   // Creates a speech recognition request and invokes its URL fetcher delegate
     25   // with the given test data.
     26   void CreateAndTestRequest(bool success, const std::string& http_response);
     27 
     28   // SpeechRecognitionRequestDelegate methods.
     29   virtual void OnSpeechRecognitionEngineResults(
     30       const SpeechRecognitionResults& results) OVERRIDE {
     31     results_ = results;
     32   }
     33 
     34   virtual void OnSpeechRecognitionEngineError(
     35       const SpeechRecognitionError& error) OVERRIDE {
     36     error_ = error.code;
     37   }
     38 
     39   // Accessor for the only result item.
     40   const SpeechRecognitionResult& result() const {
     41     DCHECK_EQ(results_.size(), 1U);
     42     return results_[0];
     43   }
     44 
     45  protected:
     46   base::MessageLoop message_loop_;
     47   net::TestURLFetcherFactory url_fetcher_factory_;
     48   SpeechRecognitionErrorCode error_;
     49   SpeechRecognitionResults results_;
     50 };
     51 
     52 void GoogleOneShotRemoteEngineTest::CreateAndTestRequest(
     53     bool success, const std::string& http_response) {
     54   GoogleOneShotRemoteEngine client(NULL);
     55   unsigned char dummy_audio_buffer_data[2] = {'\0', '\0'};
     56   scoped_refptr<AudioChunk> dummy_audio_chunk(
     57       new AudioChunk(&dummy_audio_buffer_data[0],
     58                      sizeof(dummy_audio_buffer_data),
     59                      2 /* bytes per sample */));
     60   client.set_delegate(this);
     61   client.StartRecognition();
     62   client.TakeAudioChunk(*dummy_audio_chunk.get());
     63   client.AudioChunksEnded();
     64   net::TestURLFetcher* fetcher = url_fetcher_factory_.GetFetcherByID(0);
     65   ASSERT_TRUE(fetcher);
     66 
     67   fetcher->set_url(fetcher->GetOriginalURL());
     68   net::URLRequestStatus status;
     69   status.set_status(success ? net::URLRequestStatus::SUCCESS :
     70                               net::URLRequestStatus::FAILED);
     71   fetcher->set_status(status);
     72   fetcher->set_response_code(success ? 200 : 500);
     73   fetcher->SetResponseString(http_response);
     74 
     75   fetcher->delegate()->OnURLFetchComplete(fetcher);
     76   // Parsed response will be available in result().
     77 }
     78 
     79 TEST_F(GoogleOneShotRemoteEngineTest, BasicTest) {
     80   // Normal success case with one result.
     81   CreateAndTestRequest(true,
     82       "{\"status\":0,\"hypotheses\":"
     83       "[{\"utterance\":\"123456\",\"confidence\":0.9}]}");
     84   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NONE);
     85   EXPECT_EQ(1U, result().hypotheses.size());
     86   EXPECT_EQ(ASCIIToUTF16("123456"), result().hypotheses[0].utterance);
     87   EXPECT_EQ(0.9, result().hypotheses[0].confidence);
     88 
     89   // Normal success case with multiple results.
     90   CreateAndTestRequest(true,
     91       "{\"status\":0,\"hypotheses\":["
     92       "{\"utterance\":\"hello\",\"confidence\":0.9},"
     93       "{\"utterance\":\"123456\",\"confidence\":0.5}]}");
     94   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NONE);
     95   EXPECT_EQ(2u, result().hypotheses.size());
     96   EXPECT_EQ(ASCIIToUTF16("hello"), result().hypotheses[0].utterance);
     97   EXPECT_EQ(0.9, result().hypotheses[0].confidence);
     98   EXPECT_EQ(ASCIIToUTF16("123456"), result().hypotheses[1].utterance);
     99   EXPECT_EQ(0.5, result().hypotheses[1].confidence);
    100 
    101   // Zero results.
    102   CreateAndTestRequest(true, "{\"status\":0,\"hypotheses\":[]}");
    103   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NONE);
    104   EXPECT_EQ(0U, result().hypotheses.size());
    105 
    106   // Http failure case.
    107   CreateAndTestRequest(false, std::string());
    108   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NETWORK);
    109   EXPECT_EQ(0U, result().hypotheses.size());
    110 
    111   // Invalid status case.
    112   CreateAndTestRequest(true, "{\"status\":\"invalid\",\"hypotheses\":[]}");
    113   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NETWORK);
    114   EXPECT_EQ(0U, result().hypotheses.size());
    115 
    116   // Server-side error case.
    117   CreateAndTestRequest(true, "{\"status\":1,\"hypotheses\":[]}");
    118   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NETWORK);
    119   EXPECT_EQ(0U, result().hypotheses.size());
    120 
    121   // Malformed JSON case.
    122   CreateAndTestRequest(true, "{\"status\":0,\"hypotheses\":"
    123       "[{\"unknownkey\":\"hello\"}]}");
    124   EXPECT_EQ(error_, SPEECH_RECOGNITION_ERROR_NETWORK);
    125   EXPECT_EQ(0U, result().hypotheses.size());
    126 }
    127 
    128 }  // namespace content
    129