Home | History | Annotate | Download | only in runner
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  *
      8  * 1.  Redistributions of source code must retain the above copyright
      9  *     notice, this list of conditions and the following disclaimer.
     10  * 2.  Redistributions in binary form must reproduce the above copyright
     11  *     notice, this list of conditions and the following disclaimer in the
     12  *     documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
     15  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     17  * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     19  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     20  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     21  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "MockWebSpeechRecognizer.h"
     27 
     28 #include "public/testing/WebTestDelegate.h"
     29 #include "public/web/WebSpeechRecognitionResult.h"
     30 #include "public/web/WebSpeechRecognizerClient.h"
     31 
     32 using namespace WebKit;
     33 using namespace std;
     34 
     35 namespace WebTestRunner {
     36 
     37 namespace {
     38 
     39 // Task class for calling a client function that does not take any parameters.
     40 typedef void (WebSpeechRecognizerClient::*ClientFunctionPointer)(const WebSpeechRecognitionHandle&);
     41 class ClientCallTask : public MockWebSpeechRecognizer::Task {
     42 public:
     43     ClientCallTask(MockWebSpeechRecognizer* mock, ClientFunctionPointer function)
     44         : MockWebSpeechRecognizer::Task(mock)
     45         , m_function(function)
     46     {
     47     }
     48 
     49     virtual void run() OVERRIDE { (m_recognizer->client()->*m_function)(m_recognizer->handle()); }
     50 
     51 private:
     52     ClientFunctionPointer m_function;
     53 };
     54 
     55 // Task for delivering a result event.
     56 class ResultTask : public MockWebSpeechRecognizer::Task {
     57 public:
     58     ResultTask(MockWebSpeechRecognizer* mock, const WebString transcript, float confidence)
     59         : MockWebSpeechRecognizer::Task(mock)
     60         , m_transcript(transcript)
     61         , m_confidence(confidence)
     62     {
     63     }
     64 
     65     virtual void run() OVERRIDE
     66     {
     67         WebVector<WebString> transcripts(static_cast<size_t>(1));
     68         WebVector<float> confidences(static_cast<size_t>(1));
     69         transcripts[0] = m_transcript;
     70         confidences[0] = m_confidence;
     71         WebVector<WebSpeechRecognitionResult> finalResults(static_cast<size_t>(1));
     72         WebVector<WebSpeechRecognitionResult> interimResults;
     73         finalResults[0].assign(transcripts, confidences, true);
     74 
     75         m_recognizer->client()->didReceiveResults(m_recognizer->handle(), finalResults, interimResults);
     76     }
     77 
     78 private:
     79     WebString m_transcript;
     80     float m_confidence;
     81 };
     82 
     83 // Task for delivering a nomatch event.
     84 class NoMatchTask : public MockWebSpeechRecognizer::Task {
     85 public:
     86     NoMatchTask(MockWebSpeechRecognizer* mock) : MockWebSpeechRecognizer::Task(mock) { }
     87     virtual void run() OVERRIDE { m_recognizer->client()->didReceiveNoMatch(m_recognizer->handle(), WebSpeechRecognitionResult()); }
     88 };
     89 
     90 // Task for delivering an error event.
     91 class ErrorTask : public MockWebSpeechRecognizer::Task {
     92 public:
     93     ErrorTask(MockWebSpeechRecognizer* mock, WebSpeechRecognizerClient::ErrorCode code, const WebString& message)
     94         : MockWebSpeechRecognizer::Task(mock)
     95         , m_code(code)
     96         , m_message(message)
     97     {
     98     }
     99 
    100     virtual void run() OVERRIDE { m_recognizer->client()->didReceiveError(m_recognizer->handle(), m_message, m_code); }
    101 
    102 private:
    103     WebSpeechRecognizerClient::ErrorCode m_code;
    104     WebString m_message;
    105 };
    106 
    107 } // namespace
    108 
    109 MockWebSpeechRecognizer::MockWebSpeechRecognizer()
    110     : m_wasAborted(false)
    111     , m_taskQueueRunning(false)
    112     , m_delegate(0)
    113 {
    114 }
    115 
    116 MockWebSpeechRecognizer::~MockWebSpeechRecognizer()
    117 {
    118     clearTaskQueue();
    119 }
    120 
    121 void MockWebSpeechRecognizer::setDelegate(WebTestDelegate* delegate)
    122 {
    123     m_delegate = delegate;
    124 }
    125 
    126 void MockWebSpeechRecognizer::start(const WebSpeechRecognitionHandle& handle, const WebSpeechRecognitionParams& params, WebSpeechRecognizerClient* client)
    127 {
    128     m_wasAborted = false;
    129     m_handle = handle;
    130     m_client = client;
    131 
    132     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStart));
    133     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStartAudio));
    134     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didStartSound));
    135 
    136     if (!m_mockTranscripts.empty()) {
    137         WEBKIT_ASSERT(m_mockTranscripts.size() == m_mockConfidences.size());
    138 
    139         for (size_t i = 0; i < m_mockTranscripts.size(); ++i)
    140             m_taskQueue.push_back(new ResultTask(this, m_mockTranscripts[i], m_mockConfidences[i]));
    141 
    142         m_mockTranscripts.clear();
    143         m_mockConfidences.clear();
    144     } else
    145         m_taskQueue.push_back(new NoMatchTask(this));
    146 
    147     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEndSound));
    148     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEndAudio));
    149     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd));
    150 
    151     startTaskQueue();
    152 }
    153 
    154 void MockWebSpeechRecognizer::stop(const WebSpeechRecognitionHandle& handle, WebSpeechRecognizerClient* client)
    155 {
    156     m_handle = handle;
    157     m_client = client;
    158 
    159     // FIXME: Implement.
    160     WEBKIT_ASSERT_NOT_REACHED();
    161 }
    162 
    163 void MockWebSpeechRecognizer::abort(const WebSpeechRecognitionHandle& handle, WebSpeechRecognizerClient* client)
    164 {
    165     m_handle = handle;
    166     m_client = client;
    167 
    168     clearTaskQueue();
    169     m_wasAborted = true;
    170     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd));
    171     startTaskQueue();
    172 }
    173 
    174 void MockWebSpeechRecognizer::addMockResult(const WebString& transcript, float confidence)
    175 {
    176     m_mockTranscripts.push_back(transcript);
    177     m_mockConfidences.push_back(confidence);
    178 }
    179 
    180 void MockWebSpeechRecognizer::setError(const WebString& error, const WebString& message)
    181 {
    182     WebSpeechRecognizerClient::ErrorCode code;
    183     if (error == "OtherError")
    184         code = WebSpeechRecognizerClient::OtherError;
    185     else if (error == "NoSpeechError")
    186         code = WebSpeechRecognizerClient::NoSpeechError;
    187     else if (error == "AbortedError")
    188         code = WebSpeechRecognizerClient::AbortedError;
    189     else if (error == "AudioCaptureError")
    190         code = WebSpeechRecognizerClient::AudioCaptureError;
    191     else if (error == "NetworkError")
    192         code = WebSpeechRecognizerClient::NetworkError;
    193     else if (error == "NotAllowedError")
    194         code = WebSpeechRecognizerClient::NotAllowedError;
    195     else if (error == "ServiceNotAllowedError")
    196         code = WebSpeechRecognizerClient::ServiceNotAllowedError;
    197     else if (error == "BadGrammarError")
    198         code = WebSpeechRecognizerClient::BadGrammarError;
    199     else if (error == "LanguageNotSupportedError")
    200         code = WebSpeechRecognizerClient::LanguageNotSupportedError;
    201     else
    202         return;
    203 
    204     clearTaskQueue();
    205     m_taskQueue.push_back(new ErrorTask(this, code, message));
    206     m_taskQueue.push_back(new ClientCallTask(this, &WebSpeechRecognizerClient::didEnd));
    207     startTaskQueue();
    208 }
    209 
    210 void MockWebSpeechRecognizer::startTaskQueue()
    211 {
    212     if (m_taskQueueRunning)
    213         return;
    214     m_delegate->postTask(new StepTask(this));
    215     m_taskQueueRunning = true;
    216 }
    217 
    218 void MockWebSpeechRecognizer::clearTaskQueue()
    219 {
    220     while (!m_taskQueue.empty()) {
    221         delete m_taskQueue.front();
    222         m_taskQueue.pop_front();
    223     }
    224     m_taskQueueRunning = false;
    225 }
    226 
    227 void MockWebSpeechRecognizer::StepTask::runIfValid()
    228 {
    229     if (m_object->m_taskQueue.empty()) {
    230         m_object->m_taskQueueRunning = false;
    231         return;
    232     }
    233 
    234     Task* task = m_object->m_taskQueue.front();
    235     m_object->m_taskQueue.pop_front();
    236     task->run();
    237     delete task;
    238 
    239     if (m_object->m_taskQueue.empty()) {
    240         m_object->m_taskQueueRunning = false;
    241         return;
    242     }
    243 
    244     m_object->m_delegate->postTask(new StepTask(m_object));
    245 }
    246 
    247 }
    248