tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

log_format_test.cc (66885B)


      1 //
      2 // Copyright 2022 The Abseil Authors.
      3 //
      4 // Licensed under the Apache License, Version 2.0 (the "License");
      5 // you may not use this file except in compliance with the License.
      6 // You may obtain a copy of the License at
      7 //
      8 //      https://www.apache.org/licenses/LICENSE-2.0
      9 //
     10 // Unless required by applicable law or agreed to in writing, software
     11 // distributed under the License is distributed on an "AS IS" BASIS,
     12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13 // See the License for the specific language governing permissions and
     14 // limitations under the License.
     15 
     16 #include <math.h>
     17 
     18 #include <iomanip>
     19 #include <ios>
     20 #include <limits>
     21 #include <ostream>
     22 #include <sstream>
     23 #include <string>
     24 #include <type_traits>
     25 
     26 #ifdef __ANDROID__
     27 #include <android/api-level.h>
     28 #endif
     29 #include "gmock/gmock.h"
     30 #include "gtest/gtest.h"
     31 #include "absl/log/check.h"
     32 #include "absl/log/internal/test_matchers.h"
     33 #include "absl/log/log.h"
     34 #include "absl/log/scoped_mock_log.h"
     35 #include "absl/strings/match.h"
     36 #include "absl/strings/str_cat.h"
     37 #include "absl/strings/str_format.h"
     38 #include "absl/strings/string_view.h"
     39 #include "absl/types/optional.h"
     40 
     41 namespace {
     42 using ::absl::log_internal::AsString;
     43 using ::absl::log_internal::MatchesOstream;
     44 using ::absl::log_internal::RawEncodedMessage;
     45 using ::absl::log_internal::TextMessage;
     46 using ::absl::log_internal::TextPrefix;
     47 using ::testing::AllOf;
     48 using ::testing::AnyOf;
     49 using ::testing::Each;
     50 using ::testing::EndsWith;
     51 using ::testing::Eq;
     52 using ::testing::Ge;
     53 using ::testing::IsEmpty;
     54 using ::testing::Le;
     55 using ::testing::SizeIs;
     56 using ::testing::Types;
     57 
     58 // Some aspects of formatting streamed data (e.g. pointer handling) are
     59 // implementation-defined.  Others are buggy in supported implementations.
     60 // These tests validate that the formatting matches that performed by a
     61 // `std::ostream` and also that the result is one of a list of expected formats.
     62 
     63 std::ostringstream ComparisonStream() {
     64  std::ostringstream str;
     65  str.setf(std::ios_base::showbase | std::ios_base::boolalpha |
     66           std::ios_base::internal);
     67  return str;
     68 }
     69 
     70 TEST(LogFormatTest, NoMessage) {
     71  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     72 
     73  const int log_line = __LINE__ + 1;
     74  auto do_log = [] { LOG(INFO); };
     75 
     76  EXPECT_CALL(test_sink,
     77              Send(AllOf(TextMessage(MatchesOstream(ComparisonStream())),
     78                         TextPrefix(AsString(EndsWith(absl::StrCat(
     79                             " log_format_test.cc:", log_line, "] ")))),
     80                         TextMessage(IsEmpty()),
     81                         ENCODED_MESSAGE(HasValues(IsEmpty())))));
     82 
     83  test_sink.StartCapturingLogs();
     84  do_log();
     85 }
     86 
     87 template <typename T>
     88 class CharLogFormatTest : public testing::Test {};
     89 using CharTypes = Types<char, signed char, unsigned char>;
     90 TYPED_TEST_SUITE(CharLogFormatTest, CharTypes);
     91 
     92 TYPED_TEST(CharLogFormatTest, Printable) {
     93  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
     94 
     95  const TypeParam value = 'x';
     96  auto comparison_stream = ComparisonStream();
     97  comparison_stream << value;
     98 
     99  EXPECT_CALL(
    100      test_sink,
    101      Send(AllOf(
    102          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("x")),
    103          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("x"))))))));
    104 
    105  test_sink.StartCapturingLogs();
    106  LOG(INFO) << value;
    107 }
    108 
    109 TYPED_TEST(CharLogFormatTest, Unprintable) {
    110  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    111 
    112  constexpr auto value = static_cast<TypeParam>(0xeeu);
    113  auto comparison_stream = ComparisonStream();
    114  comparison_stream << value;
    115 
    116  EXPECT_CALL(
    117      test_sink,
    118      Send(AllOf(
    119          TextMessage(MatchesOstream(comparison_stream)),
    120          TextMessage(Eq("\xee")),
    121          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("\xee"))))))));
    122 
    123  test_sink.StartCapturingLogs();
    124  LOG(INFO) << value;
    125 }
    126 
    127 template <typename T>
    128 class UnsignedIntLogFormatTest : public testing::Test {};
    129 using UnsignedIntTypes = Types<unsigned short, unsigned int,        // NOLINT
    130                               unsigned long, unsigned long long>;  // NOLINT
    131 TYPED_TEST_SUITE(UnsignedIntLogFormatTest, UnsignedIntTypes);
    132 
    133 TYPED_TEST(UnsignedIntLogFormatTest, Positive) {
    134  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    135 
    136  const TypeParam value = 224;
    137  auto comparison_stream = ComparisonStream();
    138  comparison_stream << value;
    139 
    140  EXPECT_CALL(
    141      test_sink,
    142      Send(AllOf(
    143          TextMessage(MatchesOstream(comparison_stream)),
    144          TextMessage(Eq("224")),
    145          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("224"))))))));
    146 
    147  test_sink.StartCapturingLogs();
    148  LOG(INFO) << value;
    149 }
    150 
    151 TYPED_TEST(UnsignedIntLogFormatTest, BitfieldPositive) {
    152  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    153 
    154  const struct {
    155    TypeParam bits : 6;
    156  } value{42};
    157  auto comparison_stream = ComparisonStream();
    158  comparison_stream << value.bits;
    159 
    160  EXPECT_CALL(
    161      test_sink,
    162      Send(AllOf(
    163          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("42")),
    164          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("42"))))))));
    165 
    166  test_sink.StartCapturingLogs();
    167  LOG(INFO) << value.bits;
    168 }
    169 
    170 template <typename T>
    171 class SignedIntLogFormatTest : public testing::Test {};
    172 using SignedIntTypes =
    173    Types<signed short, signed int, signed long, signed long long>;  // NOLINT
    174 TYPED_TEST_SUITE(SignedIntLogFormatTest, SignedIntTypes);
    175 
    176 TYPED_TEST(SignedIntLogFormatTest, Positive) {
    177  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    178 
    179  const TypeParam value = 224;
    180  auto comparison_stream = ComparisonStream();
    181  comparison_stream << value;
    182 
    183  EXPECT_CALL(
    184      test_sink,
    185      Send(AllOf(
    186          TextMessage(MatchesOstream(comparison_stream)),
    187          TextMessage(Eq("224")),
    188          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("224"))))))));
    189 
    190  test_sink.StartCapturingLogs();
    191  LOG(INFO) << value;
    192 }
    193 
    194 TYPED_TEST(SignedIntLogFormatTest, Negative) {
    195  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    196 
    197  const TypeParam value = -112;
    198  auto comparison_stream = ComparisonStream();
    199  comparison_stream << value;
    200 
    201  EXPECT_CALL(
    202      test_sink,
    203      Send(AllOf(
    204          TextMessage(MatchesOstream(comparison_stream)),
    205          TextMessage(Eq("-112")),
    206          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("-112"))))))));
    207 
    208  test_sink.StartCapturingLogs();
    209  LOG(INFO) << value;
    210 }
    211 
    212 TYPED_TEST(SignedIntLogFormatTest, BitfieldPositive) {
    213  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    214 
    215  const struct {
    216    TypeParam bits : 6;
    217  } value{21};
    218  auto comparison_stream = ComparisonStream();
    219  comparison_stream << value.bits;
    220 
    221  EXPECT_CALL(
    222      test_sink,
    223      Send(AllOf(
    224          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("21")),
    225          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("21"))))))));
    226 
    227  test_sink.StartCapturingLogs();
    228  LOG(INFO) << value.bits;
    229 }
    230 
    231 TYPED_TEST(SignedIntLogFormatTest, BitfieldNegative) {
    232  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    233 
    234  const struct {
    235    TypeParam bits : 6;
    236  } value{-21};
    237  auto comparison_stream = ComparisonStream();
    238  comparison_stream << value.bits;
    239 
    240  EXPECT_CALL(
    241      test_sink,
    242      Send(AllOf(
    243          TextMessage(MatchesOstream(comparison_stream)),
    244          TextMessage(Eq("-21")),
    245          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("-21"))))))));
    246 
    247  test_sink.StartCapturingLogs();
    248  LOG(INFO) << value.bits;
    249 }
    250 
    251 // Ignore these test cases on GCC due to "is too small to hold all values ..."
    252 // warning.
    253 #if !defined(__GNUC__) || defined(__clang__)
    254 // The implementation may choose a signed or unsigned integer type to represent
    255 // this enum, so it may be tested by either `UnsignedEnumLogFormatTest` or
    256 // `SignedEnumLogFormatTest`.
    257 enum MyUnsignedEnum {
    258  MyUnsignedEnum_ZERO = 0,
    259  MyUnsignedEnum_FORTY_TWO = 42,
    260  MyUnsignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
    261 };
    262 enum MyUnsignedIntEnum : unsigned int {
    263  MyUnsignedIntEnum_ZERO = 0,
    264  MyUnsignedIntEnum_FORTY_TWO = 42,
    265  MyUnsignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
    266 };
    267 
    268 template <typename T>
    269 class UnsignedEnumLogFormatTest : public testing::Test {};
    270 using UnsignedEnumTypes = std::conditional<
    271    std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
    272    Types<MyUnsignedIntEnum>, Types<MyUnsignedEnum, MyUnsignedIntEnum>>::type;
    273 TYPED_TEST_SUITE(UnsignedEnumLogFormatTest, UnsignedEnumTypes);
    274 
    275 TYPED_TEST(UnsignedEnumLogFormatTest, Positive) {
    276  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    277 
    278  const TypeParam value = static_cast<TypeParam>(224);
    279  auto comparison_stream = ComparisonStream();
    280  comparison_stream << value;
    281 
    282  EXPECT_CALL(
    283      test_sink,
    284      Send(AllOf(
    285          TextMessage(MatchesOstream(comparison_stream)),
    286          TextMessage(Eq("224")),
    287          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("224"))))))));
    288 
    289  test_sink.StartCapturingLogs();
    290  LOG(INFO) << value;
    291 }
    292 
    293 TYPED_TEST(UnsignedEnumLogFormatTest, BitfieldPositive) {
    294  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    295 
    296  const struct {
    297    TypeParam bits : 6;
    298  } value{static_cast<TypeParam>(42)};
    299  auto comparison_stream = ComparisonStream();
    300  comparison_stream << value.bits;
    301 
    302  EXPECT_CALL(
    303      test_sink,
    304      Send(AllOf(
    305          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("42")),
    306          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("42"))))))));
    307 
    308  test_sink.StartCapturingLogs();
    309  LOG(INFO) << value.bits;
    310 }
    311 
    312 enum MySignedEnum {
    313  MySignedEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
    314  MySignedEnum_NEGATIVE_TWENTY_ONE = -21,
    315  MySignedEnum_ZERO = 0,
    316  MySignedEnum_TWENTY_ONE = 21,
    317  MySignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
    318 };
    319 enum MySignedIntEnum : signed int {
    320  MySignedIntEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
    321  MySignedIntEnum_NEGATIVE_TWENTY_ONE = -21,
    322  MySignedIntEnum_ZERO = 0,
    323  MySignedIntEnum_TWENTY_ONE = 21,
    324  MySignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
    325 };
    326 
    327 template <typename T>
    328 class SignedEnumLogFormatTest : public testing::Test {};
    329 using SignedEnumTypes = std::conditional<
    330    std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
    331    Types<MyUnsignedEnum, MySignedEnum, MySignedIntEnum>,
    332    Types<MySignedEnum, MySignedIntEnum>>::type;
    333 TYPED_TEST_SUITE(SignedEnumLogFormatTest, SignedEnumTypes);
    334 
    335 TYPED_TEST(SignedEnumLogFormatTest, Positive) {
    336  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    337 
    338  const TypeParam value = static_cast<TypeParam>(224);
    339  auto comparison_stream = ComparisonStream();
    340  comparison_stream << value;
    341 
    342  EXPECT_CALL(
    343      test_sink,
    344      Send(AllOf(
    345          TextMessage(MatchesOstream(comparison_stream)),
    346          TextMessage(Eq("224")),
    347          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("224"))))))));
    348 
    349  test_sink.StartCapturingLogs();
    350  LOG(INFO) << value;
    351 }
    352 
    353 TYPED_TEST(SignedEnumLogFormatTest, Negative) {
    354  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    355 
    356  const TypeParam value = static_cast<TypeParam>(-112);
    357  auto comparison_stream = ComparisonStream();
    358  comparison_stream << value;
    359 
    360  EXPECT_CALL(
    361      test_sink,
    362      Send(AllOf(
    363          TextMessage(MatchesOstream(comparison_stream)),
    364          TextMessage(Eq("-112")),
    365          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("-112"))))))));
    366 
    367  test_sink.StartCapturingLogs();
    368  LOG(INFO) << value;
    369 }
    370 
    371 TYPED_TEST(SignedEnumLogFormatTest, BitfieldPositive) {
    372  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    373 
    374  const struct {
    375    TypeParam bits : 6;
    376  } value{static_cast<TypeParam>(21)};
    377  auto comparison_stream = ComparisonStream();
    378  comparison_stream << value.bits;
    379 
    380  EXPECT_CALL(
    381      test_sink,
    382      Send(AllOf(
    383          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("21")),
    384          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("21"))))))));
    385 
    386  test_sink.StartCapturingLogs();
    387  LOG(INFO) << value.bits;
    388 }
    389 
    390 TYPED_TEST(SignedEnumLogFormatTest, BitfieldNegative) {
    391  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    392 
    393  const struct {
    394    TypeParam bits : 6;
    395  } value{static_cast<TypeParam>(-21)};
    396  auto comparison_stream = ComparisonStream();
    397  comparison_stream << value.bits;
    398 
    399  EXPECT_CALL(
    400      test_sink,
    401      Send(AllOf(
    402          TextMessage(MatchesOstream(comparison_stream)),
    403          TextMessage(Eq("-21")),
    404          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("-21"))))))));
    405 
    406  test_sink.StartCapturingLogs();
    407  LOG(INFO) << value.bits;
    408 }
    409 #endif
    410 
    411 TEST(FloatLogFormatTest, Positive) {
    412  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    413 
    414  const float value = 6.02e23f;
    415  auto comparison_stream = ComparisonStream();
    416  comparison_stream << value;
    417 
    418  EXPECT_CALL(test_sink,
    419              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    420                         TextMessage(Eq("6.02e+23")),
    421                         ENCODED_MESSAGE(HasValues(
    422                             ElementsAre(ValueWithStr(Eq("6.02e+23"))))))));
    423 
    424  test_sink.StartCapturingLogs();
    425  LOG(INFO) << value;
    426 }
    427 
    428 TEST(FloatLogFormatTest, Negative) {
    429  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    430 
    431  const float value = -6.02e23f;
    432  auto comparison_stream = ComparisonStream();
    433  comparison_stream << value;
    434 
    435  EXPECT_CALL(test_sink,
    436              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    437                         TextMessage(Eq("-6.02e+23")),
    438                         ENCODED_MESSAGE(HasValues(
    439                             ElementsAre(ValueWithStr(Eq("-6.02e+23"))))))));
    440 
    441  test_sink.StartCapturingLogs();
    442  LOG(INFO) << value;
    443 }
    444 
    445 TEST(FloatLogFormatTest, NegativeExponent) {
    446  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    447 
    448  const float value = 6.02e-23f;
    449  auto comparison_stream = ComparisonStream();
    450  comparison_stream << value;
    451 
    452  EXPECT_CALL(test_sink,
    453              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    454                         TextMessage(Eq("6.02e-23")),
    455                         ENCODED_MESSAGE(HasValues(
    456                             ElementsAre(ValueWithStr(Eq("6.02e-23"))))))));
    457 
    458  test_sink.StartCapturingLogs();
    459  LOG(INFO) << value;
    460 }
    461 
    462 TEST(DoubleLogFormatTest, Positive) {
    463  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    464 
    465  const double value = 6.02e23;
    466  auto comparison_stream = ComparisonStream();
    467  comparison_stream << value;
    468 
    469  EXPECT_CALL(test_sink,
    470              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    471                         TextMessage(Eq("6.02e+23")),
    472                         ENCODED_MESSAGE(HasValues(
    473                             ElementsAre(ValueWithStr(Eq("6.02e+23"))))))));
    474 
    475  test_sink.StartCapturingLogs();
    476  LOG(INFO) << value;
    477 }
    478 
    479 TEST(DoubleLogFormatTest, Negative) {
    480  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    481 
    482  const double value = -6.02e23;
    483  auto comparison_stream = ComparisonStream();
    484  comparison_stream << value;
    485 
    486  EXPECT_CALL(test_sink,
    487              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    488                         TextMessage(Eq("-6.02e+23")),
    489                         ENCODED_MESSAGE(HasValues(
    490                             ElementsAre(ValueWithStr(Eq("-6.02e+23"))))))));
    491 
    492  test_sink.StartCapturingLogs();
    493  LOG(INFO) << value;
    494 }
    495 
    496 TEST(DoubleLogFormatTest, NegativeExponent) {
    497  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    498 
    499  const double value = 6.02e-23;
    500  auto comparison_stream = ComparisonStream();
    501  comparison_stream << value;
    502 
    503  EXPECT_CALL(test_sink,
    504              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    505                         TextMessage(Eq("6.02e-23")),
    506                         ENCODED_MESSAGE(HasValues(
    507                             ElementsAre(ValueWithStr(Eq("6.02e-23"))))))));
    508 
    509  test_sink.StartCapturingLogs();
    510  LOG(INFO) << value;
    511 }
    512 
    513 template <typename T>
    514 class FloatingPointLogFormatTest : public testing::Test {};
    515 using FloatingPointTypes = Types<float, double>;
    516 TYPED_TEST_SUITE(FloatingPointLogFormatTest, FloatingPointTypes);
    517 
    518 TYPED_TEST(FloatingPointLogFormatTest, Zero) {
    519  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    520 
    521  const TypeParam value = 0.0;
    522  auto comparison_stream = ComparisonStream();
    523  comparison_stream << value;
    524 
    525  EXPECT_CALL(
    526      test_sink,
    527      Send(AllOf(
    528          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("0")),
    529          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("0"))))))));
    530 
    531  test_sink.StartCapturingLogs();
    532  LOG(INFO) << value;
    533 }
    534 
    535 TYPED_TEST(FloatingPointLogFormatTest, Integer) {
    536  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    537 
    538  const TypeParam value = 1.0;
    539  auto comparison_stream = ComparisonStream();
    540  comparison_stream << value;
    541 
    542  EXPECT_CALL(
    543      test_sink,
    544      Send(AllOf(
    545          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("1")),
    546          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("1"))))))));
    547 
    548  test_sink.StartCapturingLogs();
    549  LOG(INFO) << value;
    550 }
    551 
    552 TYPED_TEST(FloatingPointLogFormatTest, Infinity) {
    553  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    554 
    555  const TypeParam value = std::numeric_limits<TypeParam>::infinity();
    556  auto comparison_stream = ComparisonStream();
    557  comparison_stream << value;
    558 
    559  EXPECT_CALL(
    560      test_sink,
    561      Send(AllOf(
    562          TextMessage(MatchesOstream(comparison_stream)),
    563          TextMessage(AnyOf(Eq("inf"), Eq("Inf"))),
    564          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("inf"))))))));
    565 
    566  test_sink.StartCapturingLogs();
    567  LOG(INFO) << value;
    568 }
    569 
    570 TYPED_TEST(FloatingPointLogFormatTest, NegativeInfinity) {
    571  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    572 
    573  const TypeParam value = -std::numeric_limits<TypeParam>::infinity();
    574  auto comparison_stream = ComparisonStream();
    575  comparison_stream << value;
    576 
    577  EXPECT_CALL(
    578      test_sink,
    579      Send(AllOf(
    580          TextMessage(MatchesOstream(comparison_stream)),
    581          TextMessage(AnyOf(Eq("-inf"), Eq("-Inf"))),
    582          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("-inf"))))))));
    583 
    584  test_sink.StartCapturingLogs();
    585  LOG(INFO) << value;
    586 }
    587 
    588 TYPED_TEST(FloatingPointLogFormatTest, NaN) {
    589  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    590 
    591  const TypeParam value = std::numeric_limits<TypeParam>::quiet_NaN();
    592  auto comparison_stream = ComparisonStream();
    593  comparison_stream << value;
    594 
    595  EXPECT_CALL(
    596      test_sink,
    597      Send(AllOf(
    598          TextMessage(MatchesOstream(comparison_stream)),
    599          TextMessage(AnyOf(Eq("nan"), Eq("NaN"))),
    600          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("nan"))))))));
    601  test_sink.StartCapturingLogs();
    602  LOG(INFO) << value;
    603 }
    604 
    605 TYPED_TEST(FloatingPointLogFormatTest, NegativeNaN) {
    606  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    607 
    608  const TypeParam value =
    609      std::copysign(std::numeric_limits<TypeParam>::quiet_NaN(), -1.0);
    610  auto comparison_stream = ComparisonStream();
    611  comparison_stream << value;
    612 
    613  // On RISC-V, don't expect that formatting -NaN produces the same string as
    614  // streaming it. #ifdefing out just the relevant line breaks the MSVC build,
    615  // so duplicate the entire EXPECT_CALL.
    616 #ifdef __riscv
    617  EXPECT_CALL(test_sink,
    618              Send(AllOf(TextMessage(AnyOf(Eq("-nan"), Eq("nan"), Eq("NaN"),
    619                                           Eq("-nan(ind)"))),
    620                         ENCODED_MESSAGE(HasValues(ElementsAre(AnyOf(
    621                             ValueWithStr(Eq("-nan")), ValueWithStr(Eq("nan")),
    622                             ValueWithStr(Eq("-nan(ind)")))))))));
    623 #else
    624  EXPECT_CALL(test_sink,
    625              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    626                         TextMessage(AnyOf(Eq("-nan"), Eq("nan"), Eq("NaN"),
    627                                           Eq("-nan(ind)"))),
    628                         ENCODED_MESSAGE(HasValues(ElementsAre(AnyOf(
    629                             ValueWithStr(Eq("-nan")), ValueWithStr(Eq("nan")),
    630                             ValueWithStr(Eq("-nan(ind)")))))))));
    631 #endif
    632  test_sink.StartCapturingLogs();
    633  LOG(INFO) << value;
    634 }
    635 
    636 template <typename T>
    637 class VoidPtrLogFormatTest : public testing::Test {};
    638 using VoidPtrTypes = Types<void *, const void *>;
    639 TYPED_TEST_SUITE(VoidPtrLogFormatTest, VoidPtrTypes);
    640 
    641 TYPED_TEST(VoidPtrLogFormatTest, Null) {
    642  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    643 
    644  const TypeParam value = nullptr;
    645  auto comparison_stream = ComparisonStream();
    646  comparison_stream << value;
    647 
    648  EXPECT_CALL(
    649      test_sink,
    650      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    651                 TextMessage(AnyOf(Eq("(nil)"), Eq("0"), Eq("0x0"),
    652                                   Eq("00000000"), Eq("0000000000000000"))))));
    653 
    654  test_sink.StartCapturingLogs();
    655  LOG(INFO) << value;
    656 }
    657 
    658 TYPED_TEST(VoidPtrLogFormatTest, NonNull) {
    659  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    660 
    661  const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefULL);
    662  auto comparison_stream = ComparisonStream();
    663  comparison_stream << value;
    664 
    665  EXPECT_CALL(test_sink,
    666              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    667                         TextMessage(AnyOf(Eq("0xdeadbeef"), Eq("DEADBEEF"),
    668                                           Eq("00000000DEADBEEF"))),
    669                         ENCODED_MESSAGE(HasValues(ElementsAre(
    670                             AnyOf(ValueWithStr(Eq("0xdeadbeef")),
    671                                   ValueWithStr(Eq("00000000DEADBEEF")))))))));
    672 
    673  test_sink.StartCapturingLogs();
    674  LOG(INFO) << value;
    675 }
    676 
    677 template <typename T>
    678 class VolatilePtrLogFormatTest : public testing::Test {};
    679 using VolatilePtrTypes =
    680    Types<volatile void*, const volatile void*, volatile char*,
    681          const volatile char*, volatile signed char*,
    682          const volatile signed char*, volatile unsigned char*,
    683          const volatile unsigned char*>;
    684 TYPED_TEST_SUITE(VolatilePtrLogFormatTest, VolatilePtrTypes);
    685 
    686 TYPED_TEST(VolatilePtrLogFormatTest, Null) {
    687  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    688 
    689  const TypeParam value = nullptr;
    690  auto comparison_stream = ComparisonStream();
    691  comparison_stream << value;
    692 
    693  // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1147r1.html
    694 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202302L
    695  EXPECT_CALL(
    696      test_sink,
    697      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    698                 TextMessage(AnyOf(Eq("(nil)"), Eq("0"), Eq("0x0"),
    699                                   Eq("00000000"), Eq("0000000000000000"))))));
    700 #else
    701  EXPECT_CALL(
    702      test_sink,
    703      Send(AllOf(
    704          TextMessage(MatchesOstream(comparison_stream)),
    705          TextMessage(Eq("false")),
    706          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("false"))))))));
    707 #endif
    708 
    709  test_sink.StartCapturingLogs();
    710  LOG(INFO) << value;
    711 }
    712 
    713 TYPED_TEST(VolatilePtrLogFormatTest, NonNull) {
    714  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    715 
    716  const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefLL);
    717  auto comparison_stream = ComparisonStream();
    718  comparison_stream << value;
    719 
    720  // https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1147r1.html
    721 #if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202302L
    722  EXPECT_CALL(test_sink,
    723              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    724                         TextMessage(AnyOf(Eq("0xdeadbeef"), Eq("DEADBEEF"),
    725                                           Eq("00000000DEADBEEF"))),
    726                         ENCODED_MESSAGE(HasValues(ElementsAre(
    727                             AnyOf(ValueWithStr(Eq("0xdeadbeef")),
    728                                   ValueWithStr(Eq("00000000DEADBEEF")))))))));
    729 #else
    730  EXPECT_CALL(
    731      test_sink,
    732      Send(AllOf(
    733          TextMessage(MatchesOstream(comparison_stream)),
    734          TextMessage(Eq("true")),
    735          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("true"))))))));
    736 #endif
    737 
    738  test_sink.StartCapturingLogs();
    739  LOG(INFO) << value;
    740 }
    741 
    742 template <typename T>
    743 class CharPtrLogFormatTest : public testing::Test {};
    744 using CharPtrTypes = Types<char, const char, signed char, const signed char,
    745                           unsigned char, const unsigned char>;
    746 TYPED_TEST_SUITE(CharPtrLogFormatTest, CharPtrTypes);
    747 
    748 TYPED_TEST(CharPtrLogFormatTest, Null) {
    749  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    750 
    751  // Streaming `([cv] char *)nullptr` into a `std::ostream` is UB, and some C++
    752  // standard library implementations choose to crash.  We take measures to log
    753  // something useful instead of crashing, even when that differs from the
    754  // standard library in use (and thus the behavior of `std::ostream`).
    755  TypeParam* const value = nullptr;
    756 
    757  EXPECT_CALL(
    758      test_sink,
    759      Send(AllOf(
    760          // `MatchesOstream` deliberately omitted since we deliberately differ.
    761          TextMessage(Eq("(null)")), ENCODED_MESSAGE(HasValues(ElementsAre(
    762                                         ValueWithStr(Eq("(null)"))))))));
    763 
    764  test_sink.StartCapturingLogs();
    765  LOG(INFO) << value;
    766 }
    767 
    768 TYPED_TEST(CharPtrLogFormatTest, NonNull) {
    769  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    770 
    771  TypeParam data[] = {'v', 'a', 'l', 'u', 'e', '\0'};
    772  TypeParam* const value = data;
    773  auto comparison_stream = ComparisonStream();
    774  comparison_stream << value;
    775 
    776  EXPECT_CALL(
    777      test_sink,
    778      Send(AllOf(
    779          TextMessage(MatchesOstream(comparison_stream)),
    780          TextMessage(Eq("value")),
    781          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("value"))))))));
    782 
    783  test_sink.StartCapturingLogs();
    784  LOG(INFO) << value;
    785 }
    786 
    787 TEST(BoolLogFormatTest, True) {
    788  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    789 
    790  const bool value = true;
    791  auto comparison_stream = ComparisonStream();
    792  comparison_stream << value;
    793 
    794  EXPECT_CALL(
    795      test_sink,
    796      Send(AllOf(
    797          TextMessage(MatchesOstream(comparison_stream)),
    798          TextMessage(Eq("true")),
    799          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("true"))))))));
    800 
    801  test_sink.StartCapturingLogs();
    802  LOG(INFO) << value;
    803 }
    804 
    805 TEST(BoolLogFormatTest, False) {
    806  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    807 
    808  const bool value = false;
    809  auto comparison_stream = ComparisonStream();
    810  comparison_stream << value;
    811 
    812  EXPECT_CALL(
    813      test_sink,
    814      Send(AllOf(
    815          TextMessage(MatchesOstream(comparison_stream)),
    816          TextMessage(Eq("false")),
    817          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("false"))))))));
    818 
    819  test_sink.StartCapturingLogs();
    820  LOG(INFO) << value;
    821 }
    822 
    823 TEST(LogFormatTest, StringLiteral) {
    824  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    825 
    826  auto comparison_stream = ComparisonStream();
    827  comparison_stream << "value";
    828 
    829  EXPECT_CALL(test_sink,
    830              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    831                         TextMessage(Eq("value")),
    832                         ENCODED_MESSAGE(HasValues(
    833                             ElementsAre(ValueWithLiteral(Eq("value"))))))));
    834 
    835  test_sink.StartCapturingLogs();
    836  LOG(INFO) << "value";
    837 }
    838 
    839 TEST(LogFormatTest, CharArray) {
    840  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    841 
    842  char value[] = "value";
    843  auto comparison_stream = ComparisonStream();
    844  comparison_stream << value;
    845 
    846  EXPECT_CALL(
    847      test_sink,
    848      Send(AllOf(
    849          TextMessage(MatchesOstream(comparison_stream)),
    850          TextMessage(Eq("value")),
    851          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("value"))))))));
    852 
    853  test_sink.StartCapturingLogs();
    854  LOG(INFO) << value;
    855 }
    856 
    857 class CustomClass {};
    858 std::ostream& operator<<(std::ostream& os, const CustomClass&) {
    859  return os << "CustomClass{}";
    860 }
    861 
    862 TEST(LogFormatTest, Custom) {
    863  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    864 
    865  CustomClass value;
    866  auto comparison_stream = ComparisonStream();
    867  comparison_stream << value;
    868 
    869  EXPECT_CALL(test_sink,
    870              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    871                         TextMessage(Eq("CustomClass{}")),
    872                         ENCODED_MESSAGE(HasValues(ElementsAre(
    873                             ValueWithStr(Eq("CustomClass{}"))))))));
    874  test_sink.StartCapturingLogs();
    875  LOG(INFO) << value;
    876 }
    877 
    878 class CustomClassNonCopyable {
    879 public:
    880  CustomClassNonCopyable() = default;
    881  CustomClassNonCopyable(const CustomClassNonCopyable&) = delete;
    882  CustomClassNonCopyable& operator=(const CustomClassNonCopyable&) = delete;
    883 };
    884 std::ostream& operator<<(std::ostream& os, const CustomClassNonCopyable&) {
    885  return os << "CustomClassNonCopyable{}";
    886 }
    887 
    888 TEST(LogFormatTest, CustomNonCopyable) {
    889  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    890 
    891  CustomClassNonCopyable value;
    892  auto comparison_stream = ComparisonStream();
    893  comparison_stream << value;
    894 
    895  EXPECT_CALL(test_sink,
    896              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
    897                         TextMessage(Eq("CustomClassNonCopyable{}")),
    898                         ENCODED_MESSAGE(HasValues(ElementsAre(
    899                             ValueWithStr(Eq("CustomClassNonCopyable{}"))))))));
    900 
    901  test_sink.StartCapturingLogs();
    902  LOG(INFO) << value;
    903 }
    904 
    905 struct Point {
    906  template <typename Sink>
    907  friend void AbslStringify(Sink& sink, const Point& p) {
    908    absl::Format(&sink, "(%d, %d)", p.x, p.y);
    909  }
    910 
    911  int x = 10;
    912  int y = 20;
    913 };
    914 
    915 TEST(LogFormatTest, AbslStringifyExample) {
    916  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    917 
    918  Point p;
    919 
    920  EXPECT_CALL(
    921      test_sink,
    922      Send(AllOf(TextMessage(Eq("(10, 20)")), TextMessage(Eq(absl::StrCat(p))),
    923                 ENCODED_MESSAGE(
    924                     HasValues(ElementsAre(ValueWithStr(Eq("(10, 20)"))))))));
    925 
    926  test_sink.StartCapturingLogs();
    927  LOG(INFO) << p;
    928 }
    929 
    930 struct PointWithAbslStringifiyAndOstream {
    931  template <typename Sink>
    932  friend void AbslStringify(Sink& sink,
    933                            const PointWithAbslStringifiyAndOstream& p) {
    934    absl::Format(&sink, "(%d, %d)", p.x, p.y);
    935  }
    936 
    937  int x = 10;
    938  int y = 20;
    939 };
    940 
    941 ABSL_ATTRIBUTE_UNUSED std::ostream& operator<<(
    942    std::ostream& os, const PointWithAbslStringifiyAndOstream&) {
    943  return os << "Default to AbslStringify()";
    944 }
    945 
    946 TEST(LogFormatTest, CustomWithAbslStringifyAndOstream) {
    947  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    948 
    949  PointWithAbslStringifiyAndOstream p;
    950 
    951  EXPECT_CALL(
    952      test_sink,
    953      Send(AllOf(TextMessage(Eq("(10, 20)")), TextMessage(Eq(absl::StrCat(p))),
    954                 ENCODED_MESSAGE(
    955                     HasValues(ElementsAre(ValueWithStr(Eq("(10, 20)"))))))));
    956 
    957  test_sink.StartCapturingLogs();
    958  LOG(INFO) << p;
    959 }
    960 
    961 struct PointStreamsNothing {
    962  template <typename Sink>
    963  friend void AbslStringify(Sink&, const PointStreamsNothing&) {}
    964 
    965  int x = 10;
    966  int y = 20;
    967 };
    968 
    969 TEST(LogFormatTest, AbslStringifyStreamsNothing) {
    970  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    971 
    972  PointStreamsNothing p;
    973 
    974  EXPECT_CALL(
    975      test_sink,
    976      Send(AllOf(
    977          TextMessage(Eq("77")), TextMessage(Eq(absl::StrCat(p, 77))),
    978          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("77"))))))));
    979 
    980  test_sink.StartCapturingLogs();
    981  LOG(INFO) << p << 77;
    982 }
    983 
    984 struct PointMultipleAppend {
    985  template <typename Sink>
    986  friend void AbslStringify(Sink& sink, const PointMultipleAppend& p) {
    987    sink.Append("(");
    988    sink.Append(absl::StrCat(p.x, ", ", p.y, ")"));
    989  }
    990 
    991  int x = 10;
    992  int y = 20;
    993 };
    994 
    995 TEST(LogFormatTest, AbslStringifyMultipleAppend) {
    996  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
    997 
    998  PointMultipleAppend p;
    999 
   1000  EXPECT_CALL(
   1001      test_sink,
   1002      Send(AllOf(TextMessage(Eq("(10, 20)")), TextMessage(Eq(absl::StrCat(p))),
   1003                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1004                     ValueWithStr(Eq("(")), ValueWithStr(Eq("10, 20)"))))))));
   1005 
   1006  test_sink.StartCapturingLogs();
   1007  LOG(INFO) << p;
   1008 }
   1009 
   1010 TEST(ManipulatorLogFormatTest, BoolAlphaTrue) {
   1011  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1012 
   1013  const bool value = true;
   1014  auto comparison_stream = ComparisonStream();
   1015  comparison_stream << std::noboolalpha << value << " "  //
   1016                    << std::boolalpha << value << " "    //
   1017                    << std::noboolalpha << value;
   1018 
   1019  EXPECT_CALL(
   1020      test_sink,
   1021      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1022                 TextMessage(Eq("1 true 1")),
   1023                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1024                     ValueWithStr(Eq("1")), ValueWithLiteral(Eq(" ")),
   1025                     ValueWithStr(Eq("true")), ValueWithLiteral(Eq(" ")),
   1026                     ValueWithStr(Eq("1"))))))));
   1027 
   1028  test_sink.StartCapturingLogs();
   1029  LOG(INFO) << std::noboolalpha << value << " "  //
   1030            << std::boolalpha << value << " "    //
   1031            << std::noboolalpha << value;
   1032 }
   1033 
   1034 TEST(ManipulatorLogFormatTest, BoolAlphaFalse) {
   1035  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1036 
   1037  const bool value = false;
   1038  auto comparison_stream = ComparisonStream();
   1039  comparison_stream << std::noboolalpha << value << " "  //
   1040                    << std::boolalpha << value << " "    //
   1041                    << std::noboolalpha << value;
   1042 
   1043  EXPECT_CALL(
   1044      test_sink,
   1045      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1046                 TextMessage(Eq("0 false 0")),
   1047                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1048                     ValueWithStr(Eq("0")), ValueWithLiteral(Eq(" ")),
   1049                     ValueWithStr(Eq("false")), ValueWithLiteral(Eq(" ")),
   1050                     ValueWithStr(Eq("0"))))))));
   1051 
   1052  test_sink.StartCapturingLogs();
   1053  LOG(INFO) << std::noboolalpha << value << " "  //
   1054            << std::boolalpha << value << " "    //
   1055            << std::noboolalpha << value;
   1056 }
   1057 
   1058 TEST(ManipulatorLogFormatTest, ShowPoint) {
   1059  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1060 
   1061  const double value = 77.0;
   1062  auto comparison_stream = ComparisonStream();
   1063  comparison_stream << std::noshowpoint << value << " "  //
   1064                    << std::showpoint << value << " "    //
   1065                    << std::noshowpoint << value;
   1066 
   1067  EXPECT_CALL(
   1068      test_sink,
   1069      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1070                 TextMessage(Eq("77 77.0000 77")),
   1071                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1072                     ValueWithStr(Eq("77")), ValueWithLiteral(Eq(" ")),
   1073                     ValueWithStr(Eq("77.0000")), ValueWithLiteral(Eq(" ")),
   1074                     ValueWithStr(Eq("77"))))))));
   1075 
   1076  test_sink.StartCapturingLogs();
   1077  LOG(INFO) << std::noshowpoint << value << " "  //
   1078            << std::showpoint << value << " "    //
   1079            << std::noshowpoint << value;
   1080 }
   1081 
   1082 TEST(ManipulatorLogFormatTest, ShowPos) {
   1083  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1084 
   1085  const int value = 77;
   1086  auto comparison_stream = ComparisonStream();
   1087  comparison_stream << std::noshowpos << value << " "  //
   1088                    << std::showpos << value << " "    //
   1089                    << std::noshowpos << value;
   1090 
   1091  EXPECT_CALL(test_sink,
   1092              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1093                         TextMessage(Eq("77 +77 77")),
   1094                         ENCODED_MESSAGE(HasValues(ElementsAre(
   1095                             ValueWithStr(Eq("77")), ValueWithLiteral(Eq(" ")),
   1096                             ValueWithStr(Eq("+77")), ValueWithLiteral(Eq(" ")),
   1097                             ValueWithStr(Eq("77"))))))));
   1098 
   1099  test_sink.StartCapturingLogs();
   1100  LOG(INFO) << std::noshowpos << value << " "  //
   1101            << std::showpos << value << " "    //
   1102            << std::noshowpos << value;
   1103 }
   1104 
   1105 TEST(ManipulatorLogFormatTest, UppercaseFloat) {
   1106  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1107 
   1108  const double value = 7.7e7;
   1109  auto comparison_stream = ComparisonStream();
   1110  comparison_stream << std::nouppercase << value << " "  //
   1111                    << std::uppercase << value << " "    //
   1112                    << std::nouppercase << value;
   1113 
   1114  EXPECT_CALL(
   1115      test_sink,
   1116      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1117                 TextMessage(Eq("7.7e+07 7.7E+07 7.7e+07")),
   1118                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1119                     ValueWithStr(Eq("7.7e+07")), ValueWithLiteral(Eq(" ")),
   1120                     ValueWithStr(Eq("7.7E+07")), ValueWithLiteral(Eq(" ")),
   1121                     ValueWithStr(Eq("7.7e+07"))))))));
   1122 
   1123  test_sink.StartCapturingLogs();
   1124  LOG(INFO) << std::nouppercase << value << " "  //
   1125            << std::uppercase << value << " "    //
   1126            << std::nouppercase << value;
   1127 }
   1128 
   1129 TEST(ManipulatorLogFormatTest, Hex) {
   1130  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1131 
   1132  const int value = 0x77;
   1133  auto comparison_stream = ComparisonStream();
   1134  comparison_stream << std::hex << value;
   1135 
   1136  EXPECT_CALL(
   1137      test_sink,
   1138      Send(AllOf(
   1139          TextMessage(MatchesOstream(comparison_stream)),
   1140          TextMessage(Eq("0x77")),
   1141          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("0x77"))))))));
   1142  test_sink.StartCapturingLogs();
   1143  LOG(INFO) << std::hex << value;
   1144 }
   1145 
   1146 TEST(ManipulatorLogFormatTest, Oct) {
   1147  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1148 
   1149  const int value = 077;
   1150  auto comparison_stream = ComparisonStream();
   1151  comparison_stream << std::oct << value;
   1152 
   1153  EXPECT_CALL(
   1154      test_sink,
   1155      Send(AllOf(
   1156          TextMessage(MatchesOstream(comparison_stream)),
   1157          TextMessage(Eq("077")),
   1158          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("077"))))))));
   1159 
   1160  test_sink.StartCapturingLogs();
   1161  LOG(INFO) << std::oct << value;
   1162 }
   1163 
   1164 TEST(ManipulatorLogFormatTest, Dec) {
   1165  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1166 
   1167  const int value = 77;
   1168  auto comparison_stream = ComparisonStream();
   1169  comparison_stream << std::hex << std::dec << value;
   1170 
   1171  EXPECT_CALL(
   1172      test_sink,
   1173      Send(AllOf(
   1174          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("77")),
   1175          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("77"))))))));
   1176 
   1177  test_sink.StartCapturingLogs();
   1178  LOG(INFO) << std::hex << std::dec << value;
   1179 }
   1180 
   1181 TEST(ManipulatorLogFormatTest, ShowbaseHex) {
   1182  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1183 
   1184  const int value = 0x77;
   1185  auto comparison_stream = ComparisonStream();
   1186  comparison_stream << std::hex                         //
   1187                    << std::noshowbase << value << " "  //
   1188                    << std::showbase << value << " "    //
   1189                    << std::noshowbase << value;
   1190 
   1191  EXPECT_CALL(
   1192      test_sink,
   1193      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1194                 TextMessage(Eq("77 0x77 77")),
   1195                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1196                     ValueWithStr(Eq("77")), ValueWithLiteral(Eq(" ")),
   1197                     ValueWithStr(Eq("0x77")), ValueWithLiteral(Eq(" ")),
   1198                     ValueWithStr(Eq("77"))))))));
   1199 
   1200  test_sink.StartCapturingLogs();
   1201  LOG(INFO) << std::hex                         //
   1202            << std::noshowbase << value << " "  //
   1203            << std::showbase << value << " "    //
   1204            << std::noshowbase << value;
   1205 }
   1206 
   1207 TEST(ManipulatorLogFormatTest, ShowbaseOct) {
   1208  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1209 
   1210  const int value = 077;
   1211  auto comparison_stream = ComparisonStream();
   1212  comparison_stream << std::oct                         //
   1213                    << std::noshowbase << value << " "  //
   1214                    << std::showbase << value << " "    //
   1215                    << std::noshowbase << value;
   1216 
   1217  EXPECT_CALL(test_sink,
   1218              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1219                         TextMessage(Eq("77 077 77")),
   1220                         ENCODED_MESSAGE(HasValues(ElementsAre(
   1221                             ValueWithStr(Eq("77")), ValueWithLiteral(Eq(" ")),
   1222                             ValueWithStr(Eq("077")), ValueWithLiteral(Eq(" ")),
   1223                             ValueWithStr(Eq("77"))))))));
   1224 
   1225  test_sink.StartCapturingLogs();
   1226  LOG(INFO) << std::oct                         //
   1227            << std::noshowbase << value << " "  //
   1228            << std::showbase << value << " "    //
   1229            << std::noshowbase << value;
   1230 }
   1231 
   1232 TEST(ManipulatorLogFormatTest, UppercaseHex) {
   1233  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1234 
   1235  const int value = 0xbeef;
   1236  auto comparison_stream = ComparisonStream();
   1237  comparison_stream                        //
   1238      << std::hex                          //
   1239      << std::nouppercase << value << " "  //
   1240      << std::uppercase << value << " "    //
   1241      << std::nouppercase << value;
   1242 
   1243  EXPECT_CALL(
   1244      test_sink,
   1245      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1246                 TextMessage(Eq("0xbeef 0XBEEF 0xbeef")),
   1247                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1248                     ValueWithStr(Eq("0xbeef")), ValueWithLiteral(Eq(" ")),
   1249                     ValueWithStr(Eq("0XBEEF")), ValueWithLiteral(Eq(" ")),
   1250                     ValueWithStr(Eq("0xbeef"))))))));
   1251 
   1252  test_sink.StartCapturingLogs();
   1253  LOG(INFO) << std::hex                          //
   1254            << std::nouppercase << value << " "  //
   1255            << std::uppercase << value << " "    //
   1256            << std::nouppercase << value;
   1257 }
   1258 
   1259 TEST(ManipulatorLogFormatTest, FixedFloat) {
   1260  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1261 
   1262  const double value = 7.7e7;
   1263  auto comparison_stream = ComparisonStream();
   1264  comparison_stream << std::fixed << value;
   1265 
   1266  EXPECT_CALL(test_sink,
   1267              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1268                         TextMessage(Eq("77000000.000000")),
   1269                         ENCODED_MESSAGE(HasValues(ElementsAre(
   1270                             ValueWithStr(Eq("77000000.000000"))))))));
   1271 
   1272  test_sink.StartCapturingLogs();
   1273  LOG(INFO) << std::fixed << value;
   1274 }
   1275 
   1276 TEST(ManipulatorLogFormatTest, ScientificFloat) {
   1277  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1278 
   1279  const double value = 7.7e7;
   1280  auto comparison_stream = ComparisonStream();
   1281  comparison_stream << std::scientific << value;
   1282 
   1283  EXPECT_CALL(test_sink,
   1284              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1285                         TextMessage(Eq("7.700000e+07")),
   1286                         ENCODED_MESSAGE(HasValues(
   1287                             ElementsAre(ValueWithStr(Eq("7.700000e+07"))))))));
   1288 
   1289  test_sink.StartCapturingLogs();
   1290  LOG(INFO) << std::scientific << value;
   1291 }
   1292 
   1293 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
   1294 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the
   1295 // C++ standard library implements it correctly (by forwarding to printf).
   1296 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
   1297 // libstdc++ shipped C++11 support without `std::hexfloat`.
   1298 #else
   1299 TEST(ManipulatorLogFormatTest, FixedAndScientificFloat) {
   1300  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1301 
   1302  const double value = 7.7e7;
   1303  auto comparison_stream = ComparisonStream();
   1304  comparison_stream << std::setiosflags(std::ios_base::scientific |
   1305                                        std::ios_base::fixed)
   1306                    << value;
   1307 
   1308  EXPECT_CALL(
   1309      test_sink,
   1310      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1311                 TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
   1312                                   Eq("0x1.25bb500000000p+26"))),
   1313                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1314                     AnyOf(ValueWithStr(Eq("0x1.25bb5p+26")),
   1315                           ValueWithStr(Eq("0x1.25bb500000000p+26")))))))));
   1316 
   1317  test_sink.StartCapturingLogs();
   1318 
   1319  // This combination should mean the same thing as `std::hexfloat`.
   1320  LOG(INFO) << std::setiosflags(std::ios_base::scientific |
   1321                                std::ios_base::fixed)
   1322            << value;
   1323 }
   1324 #endif
   1325 
   1326 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
   1327 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the C++
   1328 // standard library supports `std::hexfloat` (by forwarding to printf).
   1329 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
   1330 // libstdc++ shipped C++11 support without `std::hexfloat`.
   1331 #else
   1332 TEST(ManipulatorLogFormatTest, HexfloatFloat) {
   1333  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1334 
   1335  const double value = 7.7e7;
   1336  auto comparison_stream = ComparisonStream();
   1337  comparison_stream << std::hexfloat << value;
   1338 
   1339  EXPECT_CALL(
   1340      test_sink,
   1341      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1342                 TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
   1343                                   Eq("0x1.25bb500000000p+26"))),
   1344                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1345                     AnyOf(ValueWithStr(Eq("0x1.25bb5p+26")),
   1346                           ValueWithStr(Eq("0x1.25bb500000000p+26")))))))));
   1347 
   1348  test_sink.StartCapturingLogs();
   1349  LOG(INFO) << std::hexfloat << value;
   1350 }
   1351 #endif
   1352 
   1353 TEST(ManipulatorLogFormatTest, DefaultFloatFloat) {
   1354  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1355 
   1356  const double value = 7.7e7;
   1357  auto comparison_stream = ComparisonStream();
   1358  comparison_stream << std::hexfloat << std::defaultfloat << value;
   1359 
   1360  EXPECT_CALL(test_sink,
   1361              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1362                         TextMessage(Eq("7.7e+07")),
   1363                         ENCODED_MESSAGE(HasValues(
   1364                             ElementsAre(ValueWithStr(Eq("7.7e+07"))))))));
   1365 
   1366  test_sink.StartCapturingLogs();
   1367  LOG(INFO) << std::hexfloat << std::defaultfloat << value;
   1368 }
   1369 
   1370 TEST(ManipulatorLogFormatTest, Ends) {
   1371  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1372 
   1373  auto comparison_stream = ComparisonStream();
   1374  comparison_stream << std::ends;
   1375 
   1376  EXPECT_CALL(test_sink,
   1377              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1378                         TextMessage(Eq(absl::string_view("\0", 1))),
   1379                         ENCODED_MESSAGE(HasValues(ElementsAre(
   1380                             ValueWithStr(Eq(absl::string_view("\0", 1)))))))));
   1381 
   1382  test_sink.StartCapturingLogs();
   1383  LOG(INFO) << std::ends;
   1384 }
   1385 
   1386 TEST(ManipulatorLogFormatTest, Endl) {
   1387  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1388 
   1389  auto comparison_stream = ComparisonStream();
   1390  comparison_stream << std::endl;
   1391 
   1392  EXPECT_CALL(
   1393      test_sink,
   1394      Send(AllOf(
   1395          TextMessage(MatchesOstream(comparison_stream)),
   1396          TextMessage(Eq("\n")),
   1397          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("\n"))))))));
   1398 
   1399  test_sink.StartCapturingLogs();
   1400  LOG(INFO) << std::endl;
   1401 }
   1402 
   1403 TEST(ManipulatorLogFormatTest, SetIosFlags) {
   1404  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1405 
   1406  const int value = 0x77;
   1407  auto comparison_stream = ComparisonStream();
   1408  comparison_stream << std::resetiosflags(std::ios_base::basefield)
   1409                    << std::setiosflags(std::ios_base::hex) << value << " "  //
   1410                    << std::resetiosflags(std::ios_base::basefield)
   1411                    << std::setiosflags(std::ios_base::dec) << value;
   1412 
   1413  EXPECT_CALL(
   1414      test_sink,
   1415      Send(AllOf(
   1416          TextMessage(MatchesOstream(comparison_stream)),
   1417          TextMessage(Eq("0x77 119")),
   1418          // `std::setiosflags` and `std::resetiosflags` aren't manipulators.
   1419          // We're unable to distinguish their return type(s) from arbitrary
   1420          // user-defined types and thus don't suppress the empty str value.
   1421          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("0x77")),
   1422                                                ValueWithLiteral(Eq(" ")),
   1423                                                ValueWithStr(Eq("119"))))))));
   1424 
   1425  test_sink.StartCapturingLogs();
   1426  LOG(INFO) << std::resetiosflags(std::ios_base::basefield)
   1427            << std::setiosflags(std::ios_base::hex) << value << " "  //
   1428            << std::resetiosflags(std::ios_base::basefield)
   1429            << std::setiosflags(std::ios_base::dec) << value;
   1430 }
   1431 
   1432 TEST(ManipulatorLogFormatTest, SetBase) {
   1433  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1434 
   1435  const int value = 0x77;
   1436  auto comparison_stream = ComparisonStream();
   1437  comparison_stream << std::setbase(16) << value << " "  //
   1438                    << std::setbase(0) << value;
   1439 
   1440  EXPECT_CALL(
   1441      test_sink,
   1442      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1443                 TextMessage(Eq("0x77 119")),
   1444                 // `std::setbase` isn't a manipulator.  We're unable to
   1445                 // distinguish its return type from arbitrary user-defined
   1446                 // types and thus don't suppress the empty str value.
   1447                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1448                     ValueWithStr(Eq("0x77")), ValueWithLiteral(Eq(" ")),
   1449                     ValueWithStr(Eq("119"))))))));
   1450 
   1451  test_sink.StartCapturingLogs();
   1452  LOG(INFO) << std::setbase(16) << value << " "  //
   1453            << std::setbase(0) << value;
   1454 }
   1455 
   1456 TEST(ManipulatorLogFormatTest, SetPrecision) {
   1457  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1458 
   1459  const double value = 6.022140857e23;
   1460  auto comparison_stream = ComparisonStream();
   1461  comparison_stream << std::setprecision(4) << value;
   1462 
   1463  EXPECT_CALL(
   1464      test_sink,
   1465      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1466                 TextMessage(Eq("6.022e+23")),
   1467                 // `std::setprecision` isn't a manipulator.  We're unable to
   1468                 // distinguish its return type from arbitrary user-defined
   1469                 // types and thus don't suppress the empty str value.
   1470                 ENCODED_MESSAGE(
   1471                     HasValues(ElementsAre(ValueWithStr(Eq("6.022e+23"))))))));
   1472 
   1473  test_sink.StartCapturingLogs();
   1474  LOG(INFO) << std::setprecision(4) << value;
   1475 }
   1476 
   1477 TEST(ManipulatorLogFormatTest, SetPrecisionOverflow) {
   1478  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1479 
   1480  const double value = 6.022140857e23;
   1481  auto comparison_stream = ComparisonStream();
   1482  comparison_stream << std::setprecision(200) << value;
   1483 
   1484  EXPECT_CALL(test_sink,
   1485              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1486                         TextMessage(Eq("602214085700000015187968")),
   1487                         ENCODED_MESSAGE(HasValues(ElementsAre(
   1488                             ValueWithStr(Eq("602214085700000015187968"))))))));
   1489 
   1490  test_sink.StartCapturingLogs();
   1491  LOG(INFO) << std::setprecision(200) << value;
   1492 }
   1493 
   1494 TEST(ManipulatorLogFormatTest, SetW) {
   1495  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1496 
   1497  const int value = 77;
   1498  auto comparison_stream = ComparisonStream();
   1499  comparison_stream << std::setw(8) << value;
   1500 
   1501  EXPECT_CALL(
   1502      test_sink,
   1503      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1504                 TextMessage(Eq("      77")),
   1505                 // `std::setw` isn't a manipulator.  We're unable to
   1506                 // distinguish its return type from arbitrary user-defined
   1507                 // types and thus don't suppress the empty str value.
   1508                 ENCODED_MESSAGE(
   1509                     HasValues(ElementsAre(ValueWithStr(Eq("      77"))))))));
   1510 
   1511  test_sink.StartCapturingLogs();
   1512  LOG(INFO) << std::setw(8) << value;
   1513 }
   1514 
   1515 TEST(ManipulatorLogFormatTest, Left) {
   1516  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1517 
   1518  const int value = -77;
   1519  auto comparison_stream = ComparisonStream();
   1520  comparison_stream << std::left << std::setw(8) << value;
   1521 
   1522  EXPECT_CALL(test_sink,
   1523              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1524                         TextMessage(Eq("-77     ")),
   1525                         ENCODED_MESSAGE(HasValues(
   1526                             ElementsAre(ValueWithStr(Eq("-77     "))))))));
   1527 
   1528  test_sink.StartCapturingLogs();
   1529  LOG(INFO) << std::left << std::setw(8) << value;
   1530 }
   1531 
   1532 TEST(ManipulatorLogFormatTest, Right) {
   1533  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1534 
   1535  const int value = -77;
   1536  auto comparison_stream = ComparisonStream();
   1537  comparison_stream << std::right << std::setw(8) << value;
   1538 
   1539  EXPECT_CALL(test_sink,
   1540              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1541                         TextMessage(Eq("     -77")),
   1542                         ENCODED_MESSAGE(HasValues(
   1543                             ElementsAre(ValueWithStr(Eq("     -77"))))))));
   1544 
   1545  test_sink.StartCapturingLogs();
   1546  LOG(INFO) << std::right << std::setw(8) << value;
   1547 }
   1548 
   1549 TEST(ManipulatorLogFormatTest, Internal) {
   1550  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1551 
   1552  const int value = -77;
   1553  auto comparison_stream = ComparisonStream();
   1554  comparison_stream << std::internal << std::setw(8) << value;
   1555 
   1556  EXPECT_CALL(test_sink,
   1557              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1558                         TextMessage(Eq("-     77")),
   1559                         ENCODED_MESSAGE(HasValues(
   1560                             ElementsAre(ValueWithStr(Eq("-     77"))))))));
   1561 
   1562  test_sink.StartCapturingLogs();
   1563  LOG(INFO) << std::internal << std::setw(8) << value;
   1564 }
   1565 
   1566 TEST(ManipulatorLogFormatTest, SetFill) {
   1567  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1568 
   1569  const int value = 77;
   1570  auto comparison_stream = ComparisonStream();
   1571  comparison_stream << std::setfill('0') << std::setw(8) << value;
   1572 
   1573  EXPECT_CALL(test_sink,
   1574              Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1575                         TextMessage(Eq("00000077")),
   1576                         // `std::setfill` isn't a manipulator.  We're
   1577                         // unable to distinguish its return
   1578                         // type from arbitrary user-defined types and
   1579                         // thus don't suppress the empty str value.
   1580                         ENCODED_MESSAGE(HasValues(
   1581                             ElementsAre(ValueWithStr(Eq("00000077"))))))));
   1582 
   1583  test_sink.StartCapturingLogs();
   1584  LOG(INFO) << std::setfill('0') << std::setw(8) << value;
   1585 }
   1586 
   1587 class FromCustomClass {};
   1588 std::ostream& operator<<(std::ostream& os, const FromCustomClass&) {
   1589  return os << "FromCustomClass{}" << std::hex;
   1590 }
   1591 
   1592 TEST(ManipulatorLogFormatTest, FromCustom) {
   1593  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1594 
   1595  FromCustomClass value;
   1596  auto comparison_stream = ComparisonStream();
   1597  comparison_stream << value << " " << 0x77;
   1598 
   1599  EXPECT_CALL(
   1600      test_sink,
   1601      Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
   1602                 TextMessage(Eq("FromCustomClass{} 0x77")),
   1603                 ENCODED_MESSAGE(HasValues(ElementsAre(
   1604                     ValueWithStr(Eq("FromCustomClass{}")),
   1605                     ValueWithLiteral(Eq(" ")), ValueWithStr(Eq("0x77"))))))));
   1606 
   1607  test_sink.StartCapturingLogs();
   1608  LOG(INFO) << value << " " << 0x77;
   1609 }
   1610 
   1611 class StreamsNothing {};
   1612 std::ostream& operator<<(std::ostream& os, const StreamsNothing&) { return os; }
   1613 
   1614 TEST(ManipulatorLogFormatTest, CustomClassStreamsNothing) {
   1615  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1616 
   1617  StreamsNothing value;
   1618  auto comparison_stream = ComparisonStream();
   1619  comparison_stream << value << 77;
   1620 
   1621  EXPECT_CALL(
   1622      test_sink,
   1623      Send(AllOf(
   1624          TextMessage(MatchesOstream(comparison_stream)), TextMessage(Eq("77")),
   1625          ENCODED_MESSAGE(HasValues(ElementsAre(ValueWithStr(Eq("77"))))))));
   1626 
   1627  test_sink.StartCapturingLogs();
   1628  LOG(INFO) << value << 77;
   1629 }
   1630 
   1631 struct PointPercentV {
   1632  template <typename Sink>
   1633  friend void AbslStringify(Sink& sink, const PointPercentV& p) {
   1634    absl::Format(&sink, "(%v, %v)", p.x, p.y);
   1635  }
   1636 
   1637  int x = 10;
   1638  int y = 20;
   1639 };
   1640 
   1641 TEST(ManipulatorLogFormatTest, IOManipsDoNotAffectAbslStringify) {
   1642  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1643 
   1644  PointPercentV p;
   1645 
   1646  EXPECT_CALL(
   1647      test_sink,
   1648      Send(AllOf(TextMessage(Eq("(10, 20)")), TextMessage(Eq(absl::StrCat(p))),
   1649                 ENCODED_MESSAGE(
   1650                     HasValues(ElementsAre(ValueWithStr(Eq("(10, 20)"))))))));
   1651 
   1652  test_sink.StartCapturingLogs();
   1653  LOG(INFO) << std::hex << p;
   1654 }
   1655 
   1656 TEST(StructuredLoggingOverflowTest, TruncatesStrings) {
   1657  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1658 
   1659  // This message is too long and should be truncated to some unspecified size
   1660  // no greater than the buffer size but not too much less either.  It should be
   1661  // truncated rather than discarded.
   1662  EXPECT_CALL(
   1663      test_sink,
   1664      Send(AllOf(
   1665          TextMessage(AllOf(
   1666              SizeIs(AllOf(Ge(absl::log_internal::kLogMessageBufferSize - 256),
   1667                           Le(absl::log_internal::kLogMessageBufferSize))),
   1668              Each(Eq('x')))),
   1669          ENCODED_MESSAGE(HasOneStrThat(AllOf(
   1670              SizeIs(AllOf(Ge(absl::log_internal::kLogMessageBufferSize - 256),
   1671                           Le(absl::log_internal::kLogMessageBufferSize))),
   1672              Each(Eq('x'))))))));
   1673 
   1674  test_sink.StartCapturingLogs();
   1675  LOG(INFO) << std::string(2 * absl::log_internal::kLogMessageBufferSize, 'x');
   1676 }
   1677 
   1678 struct StringLike {
   1679  absl::string_view data;
   1680 };
   1681 std::ostream& operator<<(std::ostream& os, StringLike str) {
   1682  return os << str.data;
   1683 }
   1684 
   1685 TEST(StructuredLoggingOverflowTest, TruncatesInsertionOperators) {
   1686  absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1687 
   1688  // This message is too long and should be truncated to some unspecified size
   1689  // no greater than the buffer size but not too much less either.  It should be
   1690  // truncated rather than discarded.
   1691  EXPECT_CALL(
   1692      test_sink,
   1693      Send(AllOf(
   1694          TextMessage(AllOf(
   1695              SizeIs(AllOf(Ge(absl::log_internal::kLogMessageBufferSize - 256),
   1696                           Le(absl::log_internal::kLogMessageBufferSize))),
   1697              Each(Eq('x')))),
   1698          ENCODED_MESSAGE(HasOneStrThat(AllOf(
   1699              SizeIs(AllOf(Ge(absl::log_internal::kLogMessageBufferSize - 256),
   1700                           Le(absl::log_internal::kLogMessageBufferSize))),
   1701              Each(Eq('x'))))))));
   1702 
   1703  test_sink.StartCapturingLogs();
   1704  LOG(INFO) << StringLike{
   1705      std::string(2 * absl::log_internal::kLogMessageBufferSize, 'x')};
   1706 }
   1707 
   1708 // Returns the size of the largest string that will fit in a `LOG` message
   1709 // buffer with no prefix.
   1710 size_t MaxLogFieldLengthNoPrefix() {
   1711  class StringLengthExtractorSink : public absl::LogSink {
   1712   public:
   1713    void Send(const absl::LogEntry& entry) override {
   1714      CHECK(!size_.has_value());
   1715      CHECK_EQ(entry.text_message().find_first_not_of('x'),
   1716               absl::string_view::npos);
   1717      size_.emplace(entry.text_message().size());
   1718    }
   1719    size_t size() const {
   1720      CHECK(size_.has_value());
   1721      return *size_;
   1722    }
   1723 
   1724   private:
   1725    absl::optional<size_t> size_;
   1726  } extractor_sink;
   1727  LOG(INFO).NoPrefix().ToSinkOnly(&extractor_sink)
   1728      << std::string(2 * absl::log_internal::kLogMessageBufferSize, 'x');
   1729  return extractor_sink.size();
   1730 }
   1731 
   1732 TEST(StructuredLoggingOverflowTest, TruncatesStringsCleanly) {
   1733  const size_t longest_fit = MaxLogFieldLengthNoPrefix();
   1734  // To log a second value field, we need four bytes: two tag/type bytes and two
   1735  // sizes.  To put any data in the field we need a fifth byte.
   1736  {
   1737    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1738    EXPECT_CALL(test_sink,
   1739                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1740                               AllOf(SizeIs(longest_fit), Each(Eq('x'))))),
   1741                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1742    test_sink.StartCapturingLogs();
   1743    // x fits exactly, no part of y fits.
   1744    LOG(INFO).NoPrefix() << std::string(longest_fit, 'x') << "y";
   1745  }
   1746  {
   1747    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1748    EXPECT_CALL(test_sink,
   1749                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1750                               AllOf(SizeIs(longest_fit - 1), Each(Eq('x'))))),
   1751                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1752    test_sink.StartCapturingLogs();
   1753    // x fits, one byte from y's header fits but shouldn't be visible.
   1754    LOG(INFO).NoPrefix() << std::string(longest_fit - 1, 'x') << "y";
   1755  }
   1756  {
   1757    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1758    EXPECT_CALL(test_sink,
   1759                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1760                               AllOf(SizeIs(longest_fit - 2), Each(Eq('x'))))),
   1761                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1762    test_sink.StartCapturingLogs();
   1763    // x fits, two bytes from y's header fit but shouldn't be visible.
   1764    LOG(INFO).NoPrefix() << std::string(longest_fit - 2, 'x') << "y";
   1765  }
   1766  {
   1767    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1768    EXPECT_CALL(test_sink,
   1769                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1770                               AllOf(SizeIs(longest_fit - 3), Each(Eq('x'))))),
   1771                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1772    test_sink.StartCapturingLogs();
   1773    // x fits, three bytes from y's header fit but shouldn't be visible.
   1774    LOG(INFO).NoPrefix() << std::string(longest_fit - 3, 'x') << "y";
   1775  }
   1776  {
   1777    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1778    EXPECT_CALL(test_sink,
   1779                Send(AllOf(ENCODED_MESSAGE(HasOneStrAndOneLiteralThat(
   1780                               AllOf(SizeIs(longest_fit - 4), Each(Eq('x'))),
   1781                               IsEmpty())),
   1782                           RawEncodedMessage(Not(AsString(EndsWith("x")))))));
   1783    test_sink.StartCapturingLogs();
   1784    // x fits, all four bytes from y's header fit but no data bytes do, so we
   1785    // encode an empty string.
   1786    LOG(INFO).NoPrefix() << std::string(longest_fit - 4, 'x') << "y";
   1787  }
   1788  {
   1789    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1790    EXPECT_CALL(
   1791        test_sink,
   1792        Send(AllOf(ENCODED_MESSAGE(HasOneStrAndOneLiteralThat(
   1793                       AllOf(SizeIs(longest_fit - 5), Each(Eq('x'))), Eq("y"))),
   1794                   RawEncodedMessage(AsString(EndsWith("y"))))));
   1795    test_sink.StartCapturingLogs();
   1796    // x fits, y fits exactly.
   1797    LOG(INFO).NoPrefix() << std::string(longest_fit - 5, 'x') << "y";
   1798  }
   1799 }
   1800 
   1801 TEST(StructuredLoggingOverflowTest, TruncatesInsertionOperatorsCleanly) {
   1802  const size_t longest_fit = MaxLogFieldLengthNoPrefix();
   1803  // To log a second value field, we need four bytes: two tag/type bytes and two
   1804  // sizes.  To put any data in the field we need a fifth byte.
   1805  {
   1806    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1807    EXPECT_CALL(test_sink,
   1808                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1809                               AllOf(SizeIs(longest_fit), Each(Eq('x'))))),
   1810                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1811    test_sink.StartCapturingLogs();
   1812    // x fits exactly, no part of y fits.
   1813    LOG(INFO).NoPrefix() << std::string(longest_fit, 'x') << StringLike{"y"};
   1814  }
   1815  {
   1816    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1817    EXPECT_CALL(test_sink,
   1818                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1819                               AllOf(SizeIs(longest_fit - 1), Each(Eq('x'))))),
   1820                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1821    test_sink.StartCapturingLogs();
   1822    // x fits, one byte from y's header fits but shouldn't be visible.
   1823    LOG(INFO).NoPrefix() << std::string(longest_fit - 1, 'x')
   1824                         << StringLike{"y"};
   1825  }
   1826  {
   1827    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1828    EXPECT_CALL(test_sink,
   1829                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1830                               AllOf(SizeIs(longest_fit - 2), Each(Eq('x'))))),
   1831                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1832    test_sink.StartCapturingLogs();
   1833    // x fits, two bytes from y's header fit but shouldn't be visible.
   1834    LOG(INFO).NoPrefix() << std::string(longest_fit - 2, 'x')
   1835                         << StringLike{"y"};
   1836  }
   1837  {
   1838    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1839    EXPECT_CALL(test_sink,
   1840                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1841                               AllOf(SizeIs(longest_fit - 3), Each(Eq('x'))))),
   1842                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1843    test_sink.StartCapturingLogs();
   1844    // x fits, three bytes from y's header fit but shouldn't be visible.
   1845    LOG(INFO).NoPrefix() << std::string(longest_fit - 3, 'x')
   1846                         << StringLike{"y"};
   1847  }
   1848  {
   1849    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1850    EXPECT_CALL(test_sink,
   1851                Send(AllOf(ENCODED_MESSAGE(HasOneStrThat(
   1852                               AllOf(SizeIs(longest_fit - 4), Each(Eq('x'))))),
   1853                           RawEncodedMessage(AsString(EndsWith("x"))))));
   1854    test_sink.StartCapturingLogs();
   1855    // x fits, all four bytes from y's header fit but no data bytes do.  We
   1856    // don't encode an empty string here because every I/O manipulator hits this
   1857    // codepath and those shouldn't leave empty strings behind.
   1858    LOG(INFO).NoPrefix() << std::string(longest_fit - 4, 'x')
   1859                         << StringLike{"y"};
   1860  }
   1861  {
   1862    absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
   1863    EXPECT_CALL(
   1864        test_sink,
   1865        Send(AllOf(ENCODED_MESSAGE(HasTwoStrsThat(
   1866                       AllOf(SizeIs(longest_fit - 5), Each(Eq('x'))), Eq("y"))),
   1867                   RawEncodedMessage(AsString(EndsWith("y"))))));
   1868    test_sink.StartCapturingLogs();
   1869    // x fits, y fits exactly.
   1870    LOG(INFO).NoPrefix() << std::string(longest_fit - 5, 'x')
   1871                         << StringLike{"y"};
   1872  }
   1873 }
   1874 
   1875 }  // namespace