blob: 8e336a13bf8cf4fe6d4cc7966af76821f083aa02 [file] [log] [blame]
// Copyright 2026 The Abseil Authors.
//
// 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.
#include "absl/strings/internal/stringify_stream.h"
#include <cstddef>
#include <ostream>
#include <sstream>
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
namespace {
// Exercises the Append(size_t, char) overload
struct AppendNCharsTest {
size_t count;
char ch;
template <typename Sink>
friend void AbslStringify(Sink& sink, const AppendNCharsTest& t) {
sink.Append(t.count, t.ch);
}
};
TEST(StringifyStreamTest, AppendNChars) {
std::ostringstream os;
StringifyStream(os) << AppendNCharsTest{5, 'a'};
EXPECT_EQ(os.str(), "aaaaa");
}
// Exercises the Append(absl::string_view) overload
struct AppendStringViewTest {
absl::string_view v;
template <typename Sink>
friend void AbslStringify(Sink& sink, const AppendStringViewTest& t) {
sink.Append(t.v);
}
};
TEST(StringifyStreamTest, AppendStringView) {
std::ostringstream os;
StringifyStream(os) << AppendStringViewTest{"abc"};
EXPECT_EQ(os.str(), "abc");
}
// Exercises AbslFormatFlush(OStringStreamSink*, absl::string_view v)
struct AbslFormatFlushTest {
absl::string_view a, b, c;
template <typename Sink>
friend void AbslStringify(Sink& sink, const AbslFormatFlushTest& t) {
absl::Format(&sink, "%s, %s, %s", t.a, t.b, t.c);
}
};
TEST(StringifyStreamTest, AbslFormatFlush) {
std::ostringstream os;
StringifyStream(os) << AbslFormatFlushTest{"a", "b", "c"};
EXPECT_EQ(os.str(), "a, b, c");
}
// If overloads of both AbslStringify and operator<< are defined for the type,
// the operator<< overload should take precedence.
struct PreferStreamInsertionOverAbslStringifyTest {
friend std::ostream& operator<<( // NOLINT(clang-diagnostic-unused-function)
std::ostream& os, const PreferStreamInsertionOverAbslStringifyTest&) {
return os << "good";
}
template <typename Sink>
friend void AbslStringify // NOLINT(clang-diagnostic-unused-function)
(Sink& sink, const PreferStreamInsertionOverAbslStringifyTest&) {
sink.Append("bad");
}
};
TEST(StringifyStreamTest, PreferStreamInsertionOverAbslStringify) {
std::ostringstream os;
StringifyStream(os) << PreferStreamInsertionOverAbslStringifyTest{};
EXPECT_EQ(os.str(), "good");
}
} // namespace
} // namespace strings_internal
ABSL_NAMESPACE_END
} // namespace absl