blob: 1919249284c18e93abb0fe209e493b65efd28391 [file] [log] [blame]
// Copyright 2019 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_
#define EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_
#include <cctype>
#include <iterator>
#include <ostream>
#include <string>
#include "absl/memory/memory.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "public/emboss_text_util.h"
namespace emboss {
class EmbMatcher {
public:
template <typename ViewType>
explicit EmbMatcher(ViewType compare_to)
: compare_to_ok_(compare_to.Ok()),
compare_to_lines_(SplitToLines(
compare_to_ok_ ? WriteToString(compare_to, MultilineText()) : "")) {
}
template <typename ViewType>
bool MatchAndExplain(ViewType compare_from,
::testing::MatchResultListener* listener) const {
if (!compare_to_ok_) {
*listener << "View for comparison to is not OK.";
return false;
}
if (!compare_from.Ok()) {
*listener << "View for comparison from is not OK.";
return false;
}
const auto compare_from_lines =
SplitToLines(WriteToString(compare_from, MultilineText()));
if (compare_from_lines != compare_to_lines_) {
*listener << "\n"
<< ::testing::internal::edit_distance::CreateUnifiedDiff(
compare_to_lines_, compare_from_lines);
return false;
}
return true;
}
// Describes the property of a value matching this matcher.
void DescribeTo(::std::ostream* os) const { *os << "are equal"; }
// Describes the property of a value NOT matching this matcher.
void DescribeNegationTo(::std::ostream* os) const { *os << "are NOT equal"; }
private:
// Splits the given string on '\n' boundaries and returns a vector of those
// strings.
::std::vector</**/ ::std::string> SplitToLines(
const ::std::string& input) const {
constexpr char kNewLine = '\n';
::std::stringstream ss(input);
ss.ignore(::std::numeric_limits</**/ ::std::streamsize>::max(), kNewLine);
::std::vector</**/ ::std::string> lines;
for (::std::string line; ::std::getline(ss, line, kNewLine);) {
lines.push_back(::std::move(line));
}
return lines;
}
const bool compare_to_ok_;
const ::std::vector</**/ ::std::string> compare_to_lines_;
};
template <typename ViewType>
::testing::PolymorphicMatcher<EmbMatcher> EqualsEmb(ViewType view) {
return ::testing::MakePolymorphicMatcher(EmbMatcher(view));
}
} // namespace emboss
#endif // EMBOSS_PUBLIC_EMBOSS_TEST_UTIL_H_