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