1*99e0aae7SDavid Rees // Copyright 2019 Google LLC
2*99e0aae7SDavid Rees //
3*99e0aae7SDavid Rees // Licensed under the Apache License, Version 2.0 (the "License");
4*99e0aae7SDavid Rees // you may not use this file except in compliance with the License.
5*99e0aae7SDavid Rees // You may obtain a copy of the License at
6*99e0aae7SDavid Rees //
7*99e0aae7SDavid Rees // https://www.apache.org/licenses/LICENSE-2.0
8*99e0aae7SDavid Rees //
9*99e0aae7SDavid Rees // Unless required by applicable law or agreed to in writing, software
10*99e0aae7SDavid Rees // distributed under the License is distributed on an "AS IS" BASIS,
11*99e0aae7SDavid Rees // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*99e0aae7SDavid Rees // See the License for the specific language governing permissions and
13*99e0aae7SDavid Rees // limitations under the License.
14*99e0aae7SDavid Rees
15*99e0aae7SDavid Rees #ifndef EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_
16*99e0aae7SDavid Rees #define EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_
17*99e0aae7SDavid Rees
18*99e0aae7SDavid Rees #include <cctype>
19*99e0aae7SDavid Rees #include <iterator>
20*99e0aae7SDavid Rees #include <ostream>
21*99e0aae7SDavid Rees #include <string>
22*99e0aae7SDavid Rees
23*99e0aae7SDavid Rees #include "absl/memory/memory.h"
24*99e0aae7SDavid Rees #include "gmock/gmock.h"
25*99e0aae7SDavid Rees #include "gtest/gtest.h"
26*99e0aae7SDavid Rees #include "runtime/cpp/emboss_text_util.h"
27*99e0aae7SDavid Rees
28*99e0aae7SDavid Rees namespace emboss {
29*99e0aae7SDavid Rees
30*99e0aae7SDavid Rees class EmbMatcher {
31*99e0aae7SDavid Rees public:
32*99e0aae7SDavid Rees template <typename ViewType>
EmbMatcher(ViewType compare_to)33*99e0aae7SDavid Rees explicit EmbMatcher(ViewType compare_to)
34*99e0aae7SDavid Rees : compare_to_ok_(compare_to.Ok()),
35*99e0aae7SDavid Rees compare_to_lines_(SplitToLines(
36*99e0aae7SDavid Rees compare_to_ok_ ? WriteToString(compare_to, MultilineText()) : "")) {
37*99e0aae7SDavid Rees }
38*99e0aae7SDavid Rees
39*99e0aae7SDavid Rees template <typename ViewType>
MatchAndExplain(ViewType compare_from,::testing::MatchResultListener * listener)40*99e0aae7SDavid Rees bool MatchAndExplain(ViewType compare_from,
41*99e0aae7SDavid Rees ::testing::MatchResultListener* listener) const {
42*99e0aae7SDavid Rees if (!compare_to_ok_) {
43*99e0aae7SDavid Rees *listener << "View for comparison to is not OK.";
44*99e0aae7SDavid Rees return false;
45*99e0aae7SDavid Rees }
46*99e0aae7SDavid Rees
47*99e0aae7SDavid Rees if (!compare_from.Ok()) {
48*99e0aae7SDavid Rees *listener << "View for comparison from is not OK.";
49*99e0aae7SDavid Rees return false;
50*99e0aae7SDavid Rees }
51*99e0aae7SDavid Rees
52*99e0aae7SDavid Rees const auto compare_from_lines =
53*99e0aae7SDavid Rees SplitToLines(WriteToString(compare_from, MultilineText()));
54*99e0aae7SDavid Rees if (compare_from_lines != compare_to_lines_) {
55*99e0aae7SDavid Rees *listener << "\n"
56*99e0aae7SDavid Rees << ::testing::internal::edit_distance::CreateUnifiedDiff(
57*99e0aae7SDavid Rees compare_to_lines_, compare_from_lines);
58*99e0aae7SDavid Rees return false;
59*99e0aae7SDavid Rees }
60*99e0aae7SDavid Rees
61*99e0aae7SDavid Rees return true;
62*99e0aae7SDavid Rees }
63*99e0aae7SDavid Rees
64*99e0aae7SDavid Rees // Describes the property of a value matching this matcher.
DescribeTo(::std::ostream * os)65*99e0aae7SDavid Rees void DescribeTo(::std::ostream* os) const { *os << "are equal"; }
66*99e0aae7SDavid Rees
67*99e0aae7SDavid Rees // Describes the property of a value NOT matching this matcher.
DescribeNegationTo(::std::ostream * os)68*99e0aae7SDavid Rees void DescribeNegationTo(::std::ostream* os) const { *os << "are NOT equal"; }
69*99e0aae7SDavid Rees
70*99e0aae7SDavid Rees private:
71*99e0aae7SDavid Rees // Splits the given string on '\n' boundaries and returns a vector of those
72*99e0aae7SDavid Rees // strings.
SplitToLines(const::std::string & input)73*99e0aae7SDavid Rees ::std::vector</**/ ::std::string> SplitToLines(
74*99e0aae7SDavid Rees const ::std::string& input) const {
75*99e0aae7SDavid Rees constexpr char kNewLine = '\n';
76*99e0aae7SDavid Rees
77*99e0aae7SDavid Rees ::std::stringstream ss(input);
78*99e0aae7SDavid Rees ss.ignore(::std::numeric_limits</**/ ::std::streamsize>::max(), kNewLine);
79*99e0aae7SDavid Rees
80*99e0aae7SDavid Rees ::std::vector</**/ ::std::string> lines;
81*99e0aae7SDavid Rees for (::std::string line; ::std::getline(ss, line, kNewLine);) {
82*99e0aae7SDavid Rees lines.push_back(::std::move(line));
83*99e0aae7SDavid Rees }
84*99e0aae7SDavid Rees return lines;
85*99e0aae7SDavid Rees }
86*99e0aae7SDavid Rees
87*99e0aae7SDavid Rees const bool compare_to_ok_;
88*99e0aae7SDavid Rees const ::std::vector</**/ ::std::string> compare_to_lines_;
89*99e0aae7SDavid Rees };
90*99e0aae7SDavid Rees
91*99e0aae7SDavid Rees template <typename ViewType>
EqualsEmb(ViewType view)92*99e0aae7SDavid Rees ::testing::PolymorphicMatcher<EmbMatcher> EqualsEmb(ViewType view) {
93*99e0aae7SDavid Rees return ::testing::MakePolymorphicMatcher(EmbMatcher(view));
94*99e0aae7SDavid Rees }
95*99e0aae7SDavid Rees
96*99e0aae7SDavid Rees } // namespace emboss
97*99e0aae7SDavid Rees
98*99e0aae7SDavid Rees #endif // EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_
99