blob: 0e3a777af906f745324ef4722e4f91acd3d35f6a [file] [log] [blame]
// Copyright (c) 2018 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.
// Unit tests for the TTS Controller.
#include "base/values.h"
#include "chromecast/browser/tts/tts_controller_impl.h"
#include "chromecast/browser/tts/tts_platform.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/testing_pref_service.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/blink/public/platform/web_speech_synthesis_constants.h"
namespace chromecast {
class TtsControllerTest : public testing::Test {};
// Platform Tts implementation that does nothing.
class DummyTtsPlatformImpl : public TtsPlatformImpl {
public:
DummyTtsPlatformImpl() {}
~DummyTtsPlatformImpl() override {}
bool PlatformImplAvailable() override { return true; }
bool Speak(int utterance_id,
const std::string& utterance,
const std::string& lang,
const VoiceData& voice,
const UtteranceContinuousParameters& params) override {
return true;
}
bool IsSpeaking() override { return false; }
bool StopSpeaking() override { return true; }
void Pause() override {}
void Resume() override {}
void GetVoices(std::vector<VoiceData>* out_voices) override {}
std::string error() override { return std::string(); }
void clear_error() override {}
void set_error(const std::string& error) override {}
};
// Subclass of TtsController with a public ctor and dtor.
class TestableTtsController : public TtsControllerImpl {
public:
TestableTtsController() {}
~TestableTtsController() override {}
};
TEST_F(TtsControllerTest, TestTtsControllerShutdown) {
DummyTtsPlatformImpl platform_impl;
TestableTtsController* controller = new TestableTtsController();
controller->SetPlatformImpl(&platform_impl);
Utterance* utterance1 = new Utterance(nullptr);
utterance1->set_can_enqueue(true);
utterance1->set_src_id(1);
controller->SpeakOrEnqueue(utterance1);
Utterance* utterance2 = new Utterance(nullptr);
utterance2->set_can_enqueue(true);
utterance2->set_src_id(2);
controller->SpeakOrEnqueue(utterance2);
// Make sure that deleting the controller when there are pending
// utterances doesn't cause a crash.
delete controller;
}
TEST_F(TtsControllerTest, TestGetMatchingVoice) {
TtsControllerImpl* tts_controller = TtsControllerImpl::GetInstance();
{
// Calling GetMatchingVoice with no voices returns -1.
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
EXPECT_EQ(-1, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// Calling GetMatchingVoice with any voices returns the first one
// even if there are no criteria that match.
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
voices.push_back(VoiceData());
voices.push_back(VoiceData());
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// If nothing else matches, the English voice is returned.
// (In tests the language will always be English.)
Utterance utterance(nullptr);
std::vector<VoiceData> voices;
VoiceData fr_voice;
fr_voice.lang = "fr";
voices.push_back(fr_voice);
VoiceData en_voice;
en_voice.lang = "en";
voices.push_back(en_voice);
VoiceData de_voice;
de_voice.lang = "de";
voices.push_back(de_voice);
EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices));
}
{
// Check precedence of various matching criteria.
std::vector<VoiceData> voices;
VoiceData voice0;
voices.push_back(voice0);
VoiceData voice1;
voice1.gender = TTS_GENDER_FEMALE;
voices.push_back(voice1);
VoiceData voice2;
voice2.events.insert(TTS_EVENT_WORD);
voices.push_back(voice2);
VoiceData voice3;
voice3.lang = "de-DE";
voices.push_back(voice3);
VoiceData voice4;
voice4.lang = "fr-CA";
voices.push_back(voice4);
VoiceData voice5;
voice5.name = "Voice5";
voices.push_back(voice5);
VoiceData voice6;
voice6.extension_id = "id6";
voices.push_back(voice6);
Utterance utterance(nullptr);
EXPECT_EQ(0, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_gender(TTS_GENDER_FEMALE);
EXPECT_EQ(1, tts_controller->GetMatchingVoice(&utterance, voices));
std::set<TtsEventType> types;
types.insert(TTS_EVENT_WORD);
utterance.set_required_event_types(types);
EXPECT_EQ(2, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_lang("de-DE");
EXPECT_EQ(3, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_lang("fr-FR");
EXPECT_EQ(4, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_voice_name("Voice5");
EXPECT_EQ(5, tts_controller->GetMatchingVoice(&utterance, voices));
utterance.set_voice_name("");
utterance.set_extension_id("id6");
EXPECT_EQ(6, tts_controller->GetMatchingVoice(&utterance, voices));
}
}
} // namespace chromecast