Skip to content

Commit

Permalink
Introduce gMock-based MockDictionary and use it in language_aware_rew…
Browse files Browse the repository at this point in the history
…riter_test.

PiperOrigin-RevId: 494046956
  • Loading branch information
Noriyuki Takahashi authored and hiroyuki-komatsu committed Dec 9, 2022
1 parent ed98ea2 commit a8d84ca
Show file tree
Hide file tree
Showing 10 changed files with 252 additions and 116 deletions.
1 change: 1 addition & 0 deletions src/converter/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ cc_library_mozc(
deps = [
":segments",
"//testing:gunit",
"@com_google_absl//absl/strings:str_format",
],
)

Expand Down
2 changes: 2 additions & 0 deletions src/converter/segments.h
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,8 @@ class Segment final {
return os << segment.DebugString();
}

const std::deque<Candidate *> &candidates() const { return candidates_; }

// For debug. Candidate words removed through conversion process.
std::vector<Candidate> removed_candidates_for_debug_;

Expand Down
63 changes: 63 additions & 0 deletions src/converter/segments_matchers.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@
#define MOZC_CONVERTER_SEGMENTS_MATCHERS_H_

#include <algorithm>
#include <initializer_list>
#include <string>
#include <vector>

#include "converter/segments.h"
#include "testing/base/public/gmock.h"
#include "absl/strings/str_format.h"

namespace mozc {

Expand Down Expand Up @@ -134,6 +138,65 @@ MATCHER_P(EqualsSegment, segment, "") {
return true;
}

namespace internal {

// A helper function to print a container of candidate matchers.
template <typename Container>
std::string PrintCandidateMatcherArray(const Container &matchers) {
std::string str = "candidates are:\n";
int index = 0;
for (const auto &matcher : matchers) {
str += absl::StrFormat(" cand %d %s\n", index++,
::testing::PrintToString(matcher));
}
return str;
}

} // namespace internal

// A matcher for Segment to test if its candidates are equal to the given
// matchers in order. Use CandidatesAreArray() helpers to deduce matcher types.
MATCHER_P(CandidatesAreArrayMatcherImpl, matcher_array,
::mozc::internal::PrintCandidateMatcherArray(matcher_array)) {
return ::testing::Matches(::testing::ElementsAreArray(matcher_array))(
arg.candidates());
}

// Checks if a segment contains a candidate list that matches the given matchers
// in the given order. Example usage:
//
// Segment segment = ...;
// EXPECT_THAT(segment, CandidatesAreArray({
// Field(&Segment::Candidate::value, "value"),
// Field(&Segment::Candidate::key, "key"),
// });
//
// The above code checks if the first candidate's value is "value" and the
// second candidate's key is "key".
//
// Remark: Each candidate matcher should test against the pointer type
// (Segment::Candidate *). Note: Field() from gMock is applicable to pointer
// types too. See SegmentsMatchersTest.CandidatesAreArrayWithCustomMatcher for
// example.
template <typename T>
::testing::Matcher<Segment> CandidatesAreArray(
std::initializer_list<T> matchers) {
return CandidatesAreArrayMatcherImpl(matchers);
}

template <typename T>
::testing::Matcher<Segment> CandidatesAreArray(const std::vector<T> &matchers) {
return CandidatesAreArrayMatcherImpl(matchers);
}

// Checks if a segment contains one and only one candidate that matches the
// given matcher.
template <typename T>
::testing::Matcher<Segment> HasSingleCandidate(const T &matcher) {
using CandidateMatcherType = ::testing::Matcher<const Segment::Candidate *>;
return CandidatesAreArray(std::vector<CandidateMatcherType>{matcher});
}

// Checks if a segments exactly matches the given segments except for the
// following three fields:
// * pool_
Expand Down
35 changes: 35 additions & 0 deletions src/converter/segments_matchers_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@
namespace mozc {
namespace {

using ::testing::AllOf;
using ::testing::Field;
using ::testing::Matcher;
using ::testing::Not;
using ::testing::Pointee;

Segment::Candidate MakeCandidate(const std::string &key,
const std::string &value) {
Expand Down Expand Up @@ -78,6 +82,37 @@ TEST(SegmentsMatchersTest, EqualsSegment) {
EXPECT_THAT(x, Not(EqualsSegment(y)));
}

TEST(SegmentsMatchersTest, CandidatesAreArray) {
const Segment x = MakeSegment("key", {"value1", "value2"});
EXPECT_THAT(x, CandidatesAreArray({
Field(&Segment::Candidate::value, "value1"),
Field(&Segment::Candidate::key, "key"),
}));
}

TEST(SegmentsMatchersTest, CandidatesAreArrayWithCustomMatcher) {
const Segment x = MakeSegment("key", {"value1", "value2"});
constexpr auto KeyAndValueAre =
[](const auto &key,
const auto &value) -> Matcher<const Segment::Candidate *> {
return Pointee(AllOf(Field(&Segment::Candidate::key, key),
Field(&Segment::Candidate::value, value)));
};
EXPECT_THAT(x, CandidatesAreArray({
KeyAndValueAre("key", "value1"),
KeyAndValueAre("key", "value2"),
}));
}

TEST(SegmentsMatchersTest, HasSingleCandidate) {
const Segment x = MakeSegment("key", {"value"});
const Segment y = MakeSegment("key", {"value1", "value2"});
EXPECT_THAT(x,
HasSingleCandidate(Field(&Segment::Candidate::value, "value")));
EXPECT_THAT(
y, Not(HasSingleCandidate(Field(&Segment::Candidate::value, "value1"))));
}

TEST(SegmentsMatchersTest, EqualsSegments) {
Segments x;
*x.add_segment() = MakeSegment("key1", {"value1", "value2"});
Expand Down
1 change: 1 addition & 0 deletions src/dictionary/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -702,6 +702,7 @@ cc_library_mozc(
"//base:port",
"//base:util",
"//request:conversion_request",
"//testing:gunit",
"@com_google_absl//absl/strings",
],
)
Expand Down
1 change: 1 addition & 0 deletions src/dictionary/dictionary.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
'dependencies': [
'../base/absl.gyp:absl_strings',
'../base/base.gyp:base',
'../testing/testing.gyp:testing',
],
},
{
Expand Down
3 changes: 0 additions & 3 deletions src/dictionary/dictionary_mock.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,6 @@ std::unique_ptr<Token> CreateToken(const std::string &key,
return token;
}

const int DictionaryMock::kDefaultCost = 0;
const int DictionaryMock::kDummyPosId = 1;

DictionaryMock::DictionaryMock() { LOG(INFO) << "DictionaryMock is created"; }

DictionaryMock::~DictionaryMock() = default;
Expand Down
43 changes: 41 additions & 2 deletions src/dictionary/dictionary_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@
#include "dictionary/dictionary_interface.h"
#include "dictionary/dictionary_token.h"
#include "request/conversion_request.h"
#include "testing/base/public/gmock.h"
#include "absl/strings/string_view.h"

namespace mozc {
Expand All @@ -71,10 +72,48 @@ std::unique_ptr<Token> CreateToken(const std::string &key,
int rid,
Token::AttributesBitfield attributes);

class MockDictionary : public DictionaryInterface {
public:
static constexpr int kDefaultCost = 0;
static constexpr int kDefaultPosId = 1;

MockDictionary() = default;
~MockDictionary() override = default;

MOCK_METHOD(bool, HasKey, (absl::string_view key), (const, override));
MOCK_METHOD(bool, HasValue, (absl::string_view value), (const, override));
MOCK_METHOD(void, LookupPredictive,
(absl::string_view key,
const ConversionRequest &conversion_request, Callback *callback),
(const, override));
MOCK_METHOD(void, LookupPrefix,
(absl::string_view key,
const ConversionRequest &conversion_request, Callback *callback),
(const, override));
MOCK_METHOD(void, LookupExact,
(absl::string_view key,
const ConversionRequest &conversion_request, Callback *callback),
(const, override));
MOCK_METHOD(void, LookupReverse,
(absl::string_view str,
const ConversionRequest &conversion_request, Callback *callback),
(const, override));
MOCK_METHOD(bool, LookupComment,
(absl::string_view key, absl::string_view value,
const ConversionRequest &conversion_request,
std::string *comment),
(const, override));
MOCK_METHOD(void, PopulateReverseLookupCache, (absl::string_view str),
(const, override));
MOCK_METHOD(void, ClearReverseLookupCache, (), (const, override));
MOCK_METHOD(bool, Sync, (), (override));
MOCK_METHOD(bool, Reload, (), (override));
};

class DictionaryMock final : public DictionaryInterface {
public:
static const int kDefaultCost;
static const int kDummyPosId;
static constexpr int kDefaultCost = MockDictionary::kDefaultCost;
static constexpr int kDummyPosId = MockDictionary::kDefaultPosId;

DictionaryMock();

Expand Down
1 change: 1 addition & 0 deletions src/rewriter/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -464,6 +464,7 @@ cc_test_mozc(
"//composer:table",
"//config:config_handler",
"//converter:segments",
"//converter:segments_matchers",
"//data_manager/testing:mock_data_manager",
"//dictionary:dictionary_mock",
"//dictionary:pos_matcher_lib",
Expand Down
Loading

0 comments on commit a8d84ca

Please sign in to comment.