Commit f4cfab5a authored by llin@chromium.org's avatar llin@chromium.org Committed by Commit Bot

Add definition result parser.

Bug: b/144316700
Test: unit tests
Change-Id: I00b079c0a66842b48c7afaca3251b15789502cbf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1952285Reviewed-by: default avatarXiyuan Xia <xiyuan@chromium.org>
Commit-Queue: Li Lin <llin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#722552}
parent ed45cd43
......@@ -9,6 +9,8 @@ source_set("quick_answers") {
"quick_answers_model.h",
"search_result_loader.cc",
"search_result_loader.h",
"search_result_parsers/definition_result_parser.cc",
"search_result_parsers/definition_result_parser.h",
"search_result_parsers/result_parser.cc",
"search_result_parsers/result_parser.h",
"search_result_parsers/search_response_parser.cc",
......@@ -29,6 +31,7 @@ source_set("unit_tests") {
testonly = true
sources = [
"search_result_parsers/definition_result_parser_unittest.cc",
"search_result_parsers/result_parser_unittest.cc",
"search_result_parsers/search_response_parser_unittest.cc",
"search_result_parsers/unit_conversion_result_parser_unittest.cc",
......
// Copyright 2019 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.
#include "chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h"
#include <string>
#include "base/strings/stringprintf.h"
#include "base/values.h"
namespace chromeos {
namespace quick_answers {
namespace {
using base::Value;
constexpr char kQueryTermPath[] = "dictionaryResult.queryTerm";
constexpr char kDictionaryEntriesPath[] = "dictionaryResult.entries";
constexpr char kSenseFamiliesKey[] = "senseFamilies";
constexpr char kSensesKey[] = "senses";
constexpr char kDefinitionPathUnderSense[] = "definition.text";
constexpr char kPhoneticsKey[] = "phonetics";
constexpr char kPhoneticsTextKey[] = "text";
constexpr char kPhoneticsResultTemplate[] = "%s · /%s/";
} // namespace
bool DefinitionResultParser::Parse(const Value* result,
QuickAnswer* quick_answer) {
const Value* first_entry =
GetFirstListElement(*result, kDictionaryEntriesPath);
if (!first_entry) {
LOG(ERROR) << "Can't find a definition entry.";
return false;
}
// Get Definition.
const std::string* definition = ExtractDefinition(first_entry);
if (!definition) {
LOG(ERROR) << "Fail in extracting definition";
return false;
}
const std::string* phonetics = ExtractPhonetics(first_entry);
if (!phonetics) {
LOG(ERROR) << "Fail in extracting phonetics";
return false;
}
const std::string* query_term = result->FindStringPath(kQueryTermPath);
if (!query_term) {
LOG(ERROR) << "Fail in extracting query term";
return false;
}
quick_answer->primary_answer = *definition;
quick_answer->secondary_answer = base::StringPrintf(
kPhoneticsResultTemplate, query_term->c_str(), phonetics->c_str());
return true;
}
const std::string* DefinitionResultParser::ExtractDefinition(
const base::Value* definition_entry) {
const Value* first_sense_family =
GetFirstListElement(*definition_entry, kSenseFamiliesKey);
if (!first_sense_family) {
LOG(ERROR) << "Can't find a sense family.";
return nullptr;
}
const Value* first_sense =
GetFirstListElement(*first_sense_family, kSensesKey);
if (!first_sense) {
LOG(ERROR) << "Can't find a sense.";
return nullptr;
}
return first_sense->FindStringPath(kDefinitionPathUnderSense);
}
const std::string* DefinitionResultParser::ExtractPhonetics(
const base::Value* definition_entry) {
const Value* first_phonetics =
GetFirstListElement(*definition_entry, kPhoneticsKey);
if (!first_phonetics) {
LOG(ERROR) << "Can't find a phonetics.";
return nullptr;
}
return first_phonetics->FindStringPath(kPhoneticsTextKey);
}
} // namespace quick_answers
} // namespace chromeos
\ No newline at end of file
// Copyright 2019 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.
#ifndef CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_DEFINITION_RESULT_PARSER_H_
#define CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_DEFINITION_RESULT_PARSER_H_
#include "chromeos/components/quick_answers/search_result_parsers/result_parser.h"
namespace base {
class Value;
} // namespace base
namespace chromeos {
namespace quick_answers {
class DefinitionResultParser : public ResultParser {
public:
// ResultParser:
bool Parse(const base::Value* result, QuickAnswer* quick_answer) override;
private:
const std::string* ExtractDefinition(const base::Value* definition_entry);
const std::string* ExtractPhonetics(const base::Value* definition_entry);
};
} // namespace quick_answers
} // namespace chromeos
#endif // CHROMEOS_COMPONENTS_QUICK_ANSWERS_SEARCH_RESULT_PARSERS_DEFINITION_RESULT_PARSER_H_
// Copyright 2019 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.
#include "chromeos/components/quick_answers/search_result_parsers/definition_result_parser.h"
#include <memory>
#include <string>
#include "base/values.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chromeos {
namespace quick_answers {
namespace {
using base::Value;
}
class DefinitionResultParserTest : public testing::Test {
public:
DefinitionResultParserTest()
: parser_(std::make_unique<DefinitionResultParser>()) {}
DefinitionResultParserTest(const DefinitionResultParserTest&) = delete;
DefinitionResultParserTest& operator=(const DefinitionResultParserTest&) =
delete;
protected:
Value BuildDictionaryResult(const std::string& query_term,
const std::string& phonetic_str,
const std::string& definition) {
Value result(Value::Type::DICTIONARY);
if (!query_term.empty())
result.SetStringPath("dictionaryResult.queryTerm", query_term);
// Build definition entry.
Value entries(Value::Type::LIST);
Value entry(Value::Type::DICTIONARY);
// Build phonetics.
if (!phonetic_str.empty()) {
Value phonetics(Value::Type::LIST);
Value phonetic(Value::Type::DICTIONARY);
phonetic.SetStringPath("text", phonetic_str);
phonetics.Append(std::move(phonetic));
entry.SetPath("phonetics", std::move(phonetics));
}
// Build definition.
if (!definition.empty()) {
Value sense_families(Value::Type::LIST);
Value sense_family(Value::Type::DICTIONARY);
Value senses(Value::Type::LIST);
Value sense(Value::Type::DICTIONARY);
sense.SetStringPath("definition.text", definition);
senses.Append(std::move(sense));
sense_family.SetPath("senses", std::move(senses));
sense_families.Append(std::move(sense_family));
entry.SetPath("senseFamilies", std::move(sense_families));
}
entries.Append(std::move(entry));
result.SetPath("dictionaryResult.entries", std::move(entries));
return result;
}
std::unique_ptr<DefinitionResultParser> parser_;
};
TEST_F(DefinitionResultParserTest, Success) {
Value result =
BuildDictionaryResult("unfathomable", "ˌənˈfaT͟Həməb(ə)",
"incapable of being fully explored or understood.");
QuickAnswer quick_answer;
EXPECT_TRUE(parser_->Parse(&result, &quick_answer));
EXPECT_EQ("incapable of being fully explored or understood.",
quick_answer.primary_answer);
EXPECT_EQ("unfathomable · /ˌənˈfaT͟Həməb(ə)/", quick_answer.secondary_answer);
}
TEST_F(DefinitionResultParserTest, EmptyValue) {
Value result(Value::Type::DICTIONARY);
QuickAnswer quick_answer;
EXPECT_FALSE(parser_->Parse(&result, &quick_answer));
}
TEST_F(DefinitionResultParserTest, NoQueryTerm) {
Value result =
BuildDictionaryResult("", "ˌənˈfaT͟Həməb(ə)l",
"incapable of being fully explored or understood.");
QuickAnswer quick_answer;
EXPECT_FALSE(parser_->Parse(&result, &quick_answer));
}
TEST_F(DefinitionResultParserTest, NoPhonetic) {
Value result = BuildDictionaryResult(
"unfathomable", "", "incapable of being fully explored or understood.");
QuickAnswer quick_answer;
EXPECT_FALSE(parser_->Parse(&result, &quick_answer));
}
TEST_F(DefinitionResultParserTest, NoDefinition) {
Value result = BuildDictionaryResult("unfathomable", "ˌənˈfaT͟Həməb(ə)l", "");
QuickAnswer quick_answer;
EXPECT_FALSE(parser_->Parse(&result, &quick_answer));
}
} // namespace quick_answers
} // namespace chromeos
\ No newline at end of file
......@@ -16,6 +16,7 @@ namespace quick_answers {
class UnitConversionResultParser : public ResultParser {
public:
// ResultParser:
bool Parse(const base::Value* result, QuickAnswer* quick_answer) override;
};
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment