• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <limits>
20 #include <sstream>
21 #include <string>
22 #include <type_traits>
23 
24 #ifdef __ANDROID__
25 #include <android/api-level.h>
26 #endif
27 #include "gmock/gmock.h"
28 #include "gtest/gtest.h"
29 #include "absl/log/internal/config.h"
30 #include "absl/log/internal/test_matchers.h"
31 #include "absl/log/log.h"
32 #include "absl/log/scoped_mock_log.h"
33 #include "absl/strings/match.h"
34 #include "absl/strings/str_cat.h"
35 #include "absl/strings/string_view.h"
36 
37 namespace {
38 using ::absl::log_internal::MatchesOstream;
39 using ::absl::log_internal::TextMessage;
40 using ::absl::log_internal::TextPrefix;
41 
42 using ::testing::AllOf;
43 using ::testing::AnyOf;
44 using ::testing::Eq;
45 using ::testing::IsEmpty;
46 using ::testing::Truly;
47 using ::testing::Types;
48 
49 using ::testing::Each;
50 using ::testing::Ge;
51 using ::testing::Le;
52 using ::testing::SizeIs;
53 
54 // Some aspects of formatting streamed data (e.g. pointer handling) are
55 // implementation-defined.  Others are buggy in supported implementations.
56 // These tests validate that the formatting matches that performed by a
57 // `std::ostream` and also that the result is one of a list of expected formats.
58 
ComparisonStream()59 std::ostringstream ComparisonStream() {
60   std::ostringstream str;
61   str.setf(std::ios_base::showbase | std::ios_base::boolalpha |
62            std::ios_base::internal);
63   return str;
64 }
65 
TEST(LogFormatTest,NoMessage)66 TEST(LogFormatTest, NoMessage) {
67   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
68 
69   const int log_line = __LINE__ + 1;
70   auto do_log = [] { LOG(INFO); };
71 
72   EXPECT_CALL(
73       test_sink,
74       Send(AllOf(
75           TextMessage(MatchesOstream(ComparisonStream())),
76           TextPrefix(Truly([=](absl::string_view msg) {
77             return absl::EndsWith(
78                 msg, absl::StrCat(" log_format_test.cc:", log_line, "] "));
79           })),
80           TextMessage(IsEmpty()), ENCODED_MESSAGE(EqualsProto(R"pb()pb")))));
81 
82   test_sink.StartCapturingLogs();
83   do_log();
84 }
85 
86 template <typename T>
87 class CharLogFormatTest : public testing::Test {};
88 using CharTypes = Types<char, signed char, unsigned char>;
89 TYPED_TEST_SUITE(CharLogFormatTest, CharTypes);
90 
TYPED_TEST(CharLogFormatTest,Printable)91 TYPED_TEST(CharLogFormatTest, Printable) {
92   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
93 
94   const TypeParam value = 'x';
95   auto comparison_stream = ComparisonStream();
96   comparison_stream << value;
97 
98   EXPECT_CALL(
99       test_sink,
100       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
101                  TextMessage(Eq("x")),
102                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "x" })pb")))));
103 
104   test_sink.StartCapturingLogs();
105   LOG(INFO) << value;
106 }
107 
TYPED_TEST(CharLogFormatTest,Unprintable)108 TYPED_TEST(CharLogFormatTest, Unprintable) {
109   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
110 
111   constexpr auto value = static_cast<TypeParam>(0xeeu);
112   auto comparison_stream = ComparisonStream();
113   comparison_stream << value;
114 
115   EXPECT_CALL(
116       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
117                             TextMessage(Eq("\xee")),
118                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
119                                                                str: "\xee"
120                                                              })pb")))));
121 
122   test_sink.StartCapturingLogs();
123   LOG(INFO) << value;
124 }
125 
126 template <typename T>
127 class UnsignedIntLogFormatTest : public testing::Test {};
128 using UnsignedIntTypes = Types<unsigned short, unsigned int,        // NOLINT
129                                unsigned long, unsigned long long>;  // NOLINT
130 TYPED_TEST_SUITE(UnsignedIntLogFormatTest, UnsignedIntTypes);
131 
TYPED_TEST(UnsignedIntLogFormatTest,Positive)132 TYPED_TEST(UnsignedIntLogFormatTest, Positive) {
133   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
134 
135   const TypeParam value = 224;
136   auto comparison_stream = ComparisonStream();
137   comparison_stream << value;
138 
139   EXPECT_CALL(
140       test_sink,
141       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
142                  TextMessage(Eq("224")),
143                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
144 
145   test_sink.StartCapturingLogs();
146   LOG(INFO) << value;
147 }
148 
TYPED_TEST(UnsignedIntLogFormatTest,BitfieldPositive)149 TYPED_TEST(UnsignedIntLogFormatTest, BitfieldPositive) {
150   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
151 
152   const struct {
153     TypeParam bits : 6;
154   } value{42};
155   auto comparison_stream = ComparisonStream();
156   comparison_stream << value.bits;
157 
158   EXPECT_CALL(
159       test_sink,
160       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
161                  TextMessage(Eq("42")),
162                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "42" })pb")))));
163 
164   test_sink.StartCapturingLogs();
165   LOG(INFO) << value.bits;
166 }
167 
168 template <typename T>
169 class SignedIntLogFormatTest : public testing::Test {};
170 using SignedIntTypes =
171     Types<signed short, signed int, signed long, signed long long>;  // NOLINT
172 TYPED_TEST_SUITE(SignedIntLogFormatTest, SignedIntTypes);
173 
TYPED_TEST(SignedIntLogFormatTest,Positive)174 TYPED_TEST(SignedIntLogFormatTest, Positive) {
175   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
176 
177   const TypeParam value = 224;
178   auto comparison_stream = ComparisonStream();
179   comparison_stream << value;
180 
181   EXPECT_CALL(
182       test_sink,
183       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
184                  TextMessage(Eq("224")),
185                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
186 
187   test_sink.StartCapturingLogs();
188   LOG(INFO) << value;
189 }
190 
TYPED_TEST(SignedIntLogFormatTest,Negative)191 TYPED_TEST(SignedIntLogFormatTest, Negative) {
192   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
193 
194   const TypeParam value = -112;
195   auto comparison_stream = ComparisonStream();
196   comparison_stream << value;
197 
198   EXPECT_CALL(
199       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
200                             TextMessage(Eq("-112")),
201                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
202                                                                str: "-112"
203                                                              })pb")))));
204 
205   test_sink.StartCapturingLogs();
206   LOG(INFO) << value;
207 }
208 
TYPED_TEST(SignedIntLogFormatTest,BitfieldPositive)209 TYPED_TEST(SignedIntLogFormatTest, BitfieldPositive) {
210   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
211 
212   const struct {
213     TypeParam bits : 6;
214   } value{21};
215   auto comparison_stream = ComparisonStream();
216   comparison_stream << value.bits;
217 
218   EXPECT_CALL(
219       test_sink,
220       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
221                  TextMessage(Eq("21")),
222                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "21" })pb")))));
223 
224   test_sink.StartCapturingLogs();
225   LOG(INFO) << value.bits;
226 }
227 
TYPED_TEST(SignedIntLogFormatTest,BitfieldNegative)228 TYPED_TEST(SignedIntLogFormatTest, BitfieldNegative) {
229   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
230 
231   const struct {
232     TypeParam bits : 6;
233   } value{-21};
234   auto comparison_stream = ComparisonStream();
235   comparison_stream << value.bits;
236 
237   EXPECT_CALL(
238       test_sink,
239       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
240                  TextMessage(Eq("-21")),
241                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-21" })pb")))));
242 
243   test_sink.StartCapturingLogs();
244   LOG(INFO) << value.bits;
245 }
246 
247 // Ignore these test cases on GCC due to "is too small to hold all values ..."
248 // warning.
249 #if !defined(__GNUC__) || defined(__clang__)
250 // The implementation may choose a signed or unsigned integer type to represent
251 // this enum, so it may be tested by either `UnsignedEnumLogFormatTest` or
252 // `SignedEnumLogFormatTest`.
253 enum MyUnsignedEnum {
254   MyUnsignedEnum_ZERO = 0,
255   MyUnsignedEnum_FORTY_TWO = 42,
256   MyUnsignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
257 };
258 enum MyUnsignedIntEnum : unsigned int {
259   MyUnsignedIntEnum_ZERO = 0,
260   MyUnsignedIntEnum_FORTY_TWO = 42,
261   MyUnsignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
262 };
263 
264 template <typename T>
265 class UnsignedEnumLogFormatTest : public testing::Test {};
266 using UnsignedEnumTypes = std::conditional<
267     std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
268     Types<MyUnsignedIntEnum>, Types<MyUnsignedEnum, MyUnsignedIntEnum>>::type;
269 TYPED_TEST_SUITE(UnsignedEnumLogFormatTest, UnsignedEnumTypes);
270 
TYPED_TEST(UnsignedEnumLogFormatTest,Positive)271 TYPED_TEST(UnsignedEnumLogFormatTest, Positive) {
272   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
273 
274   const TypeParam value = static_cast<TypeParam>(224);
275   auto comparison_stream = ComparisonStream();
276   comparison_stream << value;
277 
278   EXPECT_CALL(
279       test_sink,
280       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
281                  TextMessage(Eq("224")),
282                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
283 
284   test_sink.StartCapturingLogs();
285   LOG(INFO) << value;
286 }
287 
TYPED_TEST(UnsignedEnumLogFormatTest,BitfieldPositive)288 TYPED_TEST(UnsignedEnumLogFormatTest, BitfieldPositive) {
289   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
290 
291   const struct {
292     TypeParam bits : 6;
293   } value{static_cast<TypeParam>(42)};
294   auto comparison_stream = ComparisonStream();
295   comparison_stream << value.bits;
296 
297   EXPECT_CALL(
298       test_sink,
299       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
300                  TextMessage(Eq("42")),
301                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "42" })pb")))));
302 
303   test_sink.StartCapturingLogs();
304   LOG(INFO) << value.bits;
305 }
306 
307 enum MySignedEnum {
308   MySignedEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
309   MySignedEnum_NEGATIVE_TWENTY_ONE = -21,
310   MySignedEnum_ZERO = 0,
311   MySignedEnum_TWENTY_ONE = 21,
312   MySignedEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
313 };
314 enum MySignedIntEnum : signed int {
315   MySignedIntEnum_NEGATIVE_ONE_HUNDRED_TWELVE = -112,
316   MySignedIntEnum_NEGATIVE_TWENTY_ONE = -21,
317   MySignedIntEnum_ZERO = 0,
318   MySignedIntEnum_TWENTY_ONE = 21,
319   MySignedIntEnum_TWO_HUNDRED_TWENTY_FOUR = 224,
320 };
321 
322 template <typename T>
323 class SignedEnumLogFormatTest : public testing::Test {};
324 using SignedEnumTypes = std::conditional<
325     std::is_signed<std::underlying_type<MyUnsignedEnum>::type>::value,
326     Types<MyUnsignedEnum, MySignedEnum, MySignedIntEnum>,
327     Types<MySignedEnum, MySignedIntEnum>>::type;
328 TYPED_TEST_SUITE(SignedEnumLogFormatTest, SignedEnumTypes);
329 
TYPED_TEST(SignedEnumLogFormatTest,Positive)330 TYPED_TEST(SignedEnumLogFormatTest, Positive) {
331   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
332 
333   const TypeParam value = static_cast<TypeParam>(224);
334   auto comparison_stream = ComparisonStream();
335   comparison_stream << value;
336 
337   EXPECT_CALL(
338       test_sink,
339       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
340                  TextMessage(Eq("224")),
341                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "224" })pb")))));
342 
343   test_sink.StartCapturingLogs();
344   LOG(INFO) << value;
345 }
346 
TYPED_TEST(SignedEnumLogFormatTest,Negative)347 TYPED_TEST(SignedEnumLogFormatTest, Negative) {
348   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
349 
350   const TypeParam value = static_cast<TypeParam>(-112);
351   auto comparison_stream = ComparisonStream();
352   comparison_stream << value;
353 
354   EXPECT_CALL(
355       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
356                             TextMessage(Eq("-112")),
357                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
358                                                                str: "-112"
359                                                              })pb")))));
360 
361   test_sink.StartCapturingLogs();
362   LOG(INFO) << value;
363 }
364 
TYPED_TEST(SignedEnumLogFormatTest,BitfieldPositive)365 TYPED_TEST(SignedEnumLogFormatTest, BitfieldPositive) {
366   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
367 
368   const struct {
369     TypeParam bits : 6;
370   } value{static_cast<TypeParam>(21)};
371   auto comparison_stream = ComparisonStream();
372   comparison_stream << value.bits;
373 
374   EXPECT_CALL(
375       test_sink,
376       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
377                  TextMessage(Eq("21")),
378                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "21" })pb")))));
379 
380   test_sink.StartCapturingLogs();
381   LOG(INFO) << value.bits;
382 }
383 
TYPED_TEST(SignedEnumLogFormatTest,BitfieldNegative)384 TYPED_TEST(SignedEnumLogFormatTest, BitfieldNegative) {
385   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
386 
387   const struct {
388     TypeParam bits : 6;
389   } value{static_cast<TypeParam>(-21)};
390   auto comparison_stream = ComparisonStream();
391   comparison_stream << value.bits;
392 
393   EXPECT_CALL(
394       test_sink,
395       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
396                  TextMessage(Eq("-21")),
397                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-21" })pb")))));
398 
399   test_sink.StartCapturingLogs();
400   LOG(INFO) << value.bits;
401 }
402 #endif
403 
TEST(FloatLogFormatTest,Positive)404 TEST(FloatLogFormatTest, Positive) {
405   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
406 
407   const float value = 6.02e23f;
408   auto comparison_stream = ComparisonStream();
409   comparison_stream << value;
410 
411   EXPECT_CALL(test_sink,
412               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
413                          TextMessage(Eq("6.02e+23")),
414                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
415                                                             str: "6.02e+23"
416                                                           })pb")))));
417 
418   test_sink.StartCapturingLogs();
419   LOG(INFO) << value;
420 }
421 
TEST(FloatLogFormatTest,Negative)422 TEST(FloatLogFormatTest, Negative) {
423   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
424 
425   const float value = -6.02e23f;
426   auto comparison_stream = ComparisonStream();
427   comparison_stream << value;
428 
429   EXPECT_CALL(test_sink,
430               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
431                          TextMessage(Eq("-6.02e+23")),
432                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
433                                                             str: "-6.02e+23"
434                                                           })pb")))));
435 
436   test_sink.StartCapturingLogs();
437   LOG(INFO) << value;
438 }
439 
TEST(FloatLogFormatTest,NegativeExponent)440 TEST(FloatLogFormatTest, NegativeExponent) {
441   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
442 
443   const float value = 6.02e-23f;
444   auto comparison_stream = ComparisonStream();
445   comparison_stream << value;
446 
447   EXPECT_CALL(test_sink,
448               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
449                          TextMessage(Eq("6.02e-23")),
450                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
451                                                             str: "6.02e-23"
452                                                           })pb")))));
453 
454   test_sink.StartCapturingLogs();
455   LOG(INFO) << value;
456 }
457 
TEST(DoubleLogFormatTest,Positive)458 TEST(DoubleLogFormatTest, Positive) {
459   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
460 
461   const double value = 6.02e23;
462   auto comparison_stream = ComparisonStream();
463   comparison_stream << value;
464 
465   EXPECT_CALL(test_sink,
466               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
467                          TextMessage(Eq("6.02e+23")),
468                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
469                                                             str: "6.02e+23"
470                                                           })pb")))));
471 
472   test_sink.StartCapturingLogs();
473   LOG(INFO) << value;
474 }
475 
TEST(DoubleLogFormatTest,Negative)476 TEST(DoubleLogFormatTest, Negative) {
477   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
478 
479   const double value = -6.02e23;
480   auto comparison_stream = ComparisonStream();
481   comparison_stream << value;
482 
483   EXPECT_CALL(test_sink,
484               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
485                          TextMessage(Eq("-6.02e+23")),
486                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
487                                                             str: "-6.02e+23"
488                                                           })pb")))));
489 
490   test_sink.StartCapturingLogs();
491   LOG(INFO) << value;
492 }
493 
TEST(DoubleLogFormatTest,NegativeExponent)494 TEST(DoubleLogFormatTest, NegativeExponent) {
495   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
496 
497   const double value = 6.02e-23;
498   auto comparison_stream = ComparisonStream();
499   comparison_stream << value;
500 
501   EXPECT_CALL(test_sink,
502               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
503                          TextMessage(Eq("6.02e-23")),
504                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
505                                                             str: "6.02e-23"
506                                                           })pb")))));
507 
508   test_sink.StartCapturingLogs();
509   LOG(INFO) << value;
510 }
511 
512 template <typename T>
513 class FloatingPointLogFormatTest : public testing::Test {};
514 using FloatingPointTypes = Types<float, double>;
515 TYPED_TEST_SUITE(FloatingPointLogFormatTest, FloatingPointTypes);
516 
TYPED_TEST(FloatingPointLogFormatTest,Zero)517 TYPED_TEST(FloatingPointLogFormatTest, Zero) {
518   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
519 
520   const TypeParam value = 0.0;
521   auto comparison_stream = ComparisonStream();
522   comparison_stream << value;
523 
524   EXPECT_CALL(
525       test_sink,
526       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
527                  TextMessage(Eq("0")),
528                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "0" })pb")))));
529 
530   test_sink.StartCapturingLogs();
531   LOG(INFO) << value;
532 }
533 
TYPED_TEST(FloatingPointLogFormatTest,Integer)534 TYPED_TEST(FloatingPointLogFormatTest, Integer) {
535   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
536 
537   const TypeParam value = 1.0;
538   auto comparison_stream = ComparisonStream();
539   comparison_stream << value;
540 
541   EXPECT_CALL(
542       test_sink,
543       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
544                  TextMessage(Eq("1")),
545                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "1" })pb")))));
546 
547   test_sink.StartCapturingLogs();
548   LOG(INFO) << value;
549 }
550 
TYPED_TEST(FloatingPointLogFormatTest,Infinity)551 TYPED_TEST(FloatingPointLogFormatTest, Infinity) {
552   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
553 
554   const TypeParam value = std::numeric_limits<TypeParam>::infinity();
555   auto comparison_stream = ComparisonStream();
556   comparison_stream << value;
557 
558   EXPECT_CALL(
559       test_sink,
560       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
561                  TextMessage(AnyOf(Eq("inf"), Eq("Inf"))),
562                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "inf" })pb")))));
563 
564   test_sink.StartCapturingLogs();
565   LOG(INFO) << value;
566 }
567 
TYPED_TEST(FloatingPointLogFormatTest,NegativeInfinity)568 TYPED_TEST(FloatingPointLogFormatTest, NegativeInfinity) {
569   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
570 
571   const TypeParam value = -std::numeric_limits<TypeParam>::infinity();
572   auto comparison_stream = ComparisonStream();
573   comparison_stream << value;
574 
575   EXPECT_CALL(
576       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
577                             TextMessage(AnyOf(Eq("-inf"), Eq("-Inf"))),
578                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
579                                                                str: "-inf"
580                                                              })pb")))));
581 
582   test_sink.StartCapturingLogs();
583   LOG(INFO) << value;
584 }
585 
TYPED_TEST(FloatingPointLogFormatTest,NaN)586 TYPED_TEST(FloatingPointLogFormatTest, NaN) {
587   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
588 
589   const TypeParam value = std::numeric_limits<TypeParam>::quiet_NaN();
590   auto comparison_stream = ComparisonStream();
591   comparison_stream << value;
592 
593   EXPECT_CALL(
594       test_sink,
595       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
596                  TextMessage(AnyOf(Eq("nan"), Eq("NaN"))),
597                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "nan" })pb")))));
598   test_sink.StartCapturingLogs();
599   LOG(INFO) << value;
600 }
601 
TYPED_TEST(FloatingPointLogFormatTest,NegativeNaN)602 TYPED_TEST(FloatingPointLogFormatTest, NegativeNaN) {
603   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
604 
605   const TypeParam value =
606       std::copysign(std::numeric_limits<TypeParam>::quiet_NaN(), -1.0);
607   auto comparison_stream = ComparisonStream();
608   comparison_stream << value;
609 
610   EXPECT_CALL(
611       test_sink,
612       Send(AllOf(
613           TextMessage(MatchesOstream(comparison_stream)),
614           TextMessage(AnyOf(Eq("-nan"), Eq("nan"), Eq("NaN"), Eq("-nan(ind)"))),
615           ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "-nan" })pb")))));
616 
617   test_sink.StartCapturingLogs();
618   LOG(INFO) << value;
619 }
620 
621 template <typename T>
622 class VoidPtrLogFormatTest : public testing::Test {};
623 using VoidPtrTypes = Types<void *, const void *>;
624 TYPED_TEST_SUITE(VoidPtrLogFormatTest, VoidPtrTypes);
625 
TYPED_TEST(VoidPtrLogFormatTest,Null)626 TYPED_TEST(VoidPtrLogFormatTest, Null) {
627   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
628 
629   const TypeParam value = nullptr;
630   auto comparison_stream = ComparisonStream();
631   comparison_stream << value;
632 
633   EXPECT_CALL(
634       test_sink,
635       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
636                  TextMessage(AnyOf(Eq("(nil)"), Eq("0"), Eq("0x0"),
637                                    Eq("00000000"), Eq("0000000000000000"))))));
638 
639   test_sink.StartCapturingLogs();
640   LOG(INFO) << value;
641 }
642 
TYPED_TEST(VoidPtrLogFormatTest,NonNull)643 TYPED_TEST(VoidPtrLogFormatTest, NonNull) {
644   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
645 
646   const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefULL);
647   auto comparison_stream = ComparisonStream();
648   comparison_stream << value;
649 
650   EXPECT_CALL(test_sink,
651               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
652                          TextMessage(AnyOf(Eq("0xdeadbeef"), Eq("DEADBEEF"),
653                                            Eq("00000000DEADBEEF"))),
654                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
655                                                             str: "0xdeadbeef"
656                                                           })pb")))));
657 
658   test_sink.StartCapturingLogs();
659   LOG(INFO) << value;
660 }
661 
662 template <typename T>
663 class VolatileVoidPtrLogFormatTest : public testing::Test {};
664 using VolatileVoidPtrTypes = Types<volatile void *, const volatile void *>;
665 TYPED_TEST_SUITE(VolatileVoidPtrLogFormatTest, VolatileVoidPtrTypes);
666 
TYPED_TEST(VolatileVoidPtrLogFormatTest,Null)667 TYPED_TEST(VolatileVoidPtrLogFormatTest, Null) {
668   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
669 
670   const TypeParam value = nullptr;
671   auto comparison_stream = ComparisonStream();
672   comparison_stream << value;
673 
674   EXPECT_CALL(
675       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
676                             TextMessage(Eq("false")),
677                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
678                                                                str: "false"
679                                                              })pb")))));
680 
681   test_sink.StartCapturingLogs();
682   LOG(INFO) << value;
683 }
684 
TYPED_TEST(VolatileVoidPtrLogFormatTest,NonNull)685 TYPED_TEST(VolatileVoidPtrLogFormatTest, NonNull) {
686   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
687 
688   const TypeParam value = reinterpret_cast<TypeParam>(0xdeadbeefLL);
689   auto comparison_stream = ComparisonStream();
690   comparison_stream << value;
691 
692   EXPECT_CALL(
693       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
694                             TextMessage(Eq("true")),
695                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
696                                                                str: "true"
697                                                              })pb")))));
698 
699   test_sink.StartCapturingLogs();
700   LOG(INFO) << value;
701 }
702 
703 template <typename T>
704 class CharPtrLogFormatTest : public testing::Test {};
705 using CharPtrTypes = Types<char *, const char *>;
706 TYPED_TEST_SUITE(CharPtrLogFormatTest, CharPtrTypes);
707 
TYPED_TEST(CharPtrLogFormatTest,Null)708 TYPED_TEST(CharPtrLogFormatTest, Null) {
709   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
710 
711   // Streaming `([cv] char *)nullptr` into a `std::ostream` is UB, and some C++
712   // standard library implementations choose to crash.  We take measures to log
713   // something useful instead of crashing, even when that differs from the
714   // standard library in use (and thus the behavior of `std::ostream`).
715   const TypeParam value = nullptr;
716 
717   EXPECT_CALL(
718       test_sink,
719       Send(AllOf(
720           // `MatchesOstream` deliberately omitted since we deliberately differ.
721           TextMessage(Eq("(null)")),
722           ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "(null)" })pb")))));
723 
724   test_sink.StartCapturingLogs();
725   LOG(INFO) << value;
726 }
727 
TYPED_TEST(CharPtrLogFormatTest,NonNull)728 TYPED_TEST(CharPtrLogFormatTest, NonNull) {
729   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
730 
731   char data[] = "value";
732   const TypeParam value = data;
733   auto comparison_stream = ComparisonStream();
734   comparison_stream << value;
735 
736   EXPECT_CALL(
737       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
738                             TextMessage(Eq("value")),
739                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
740                                                                str: "value"
741                                                              })pb")))));
742 
743   test_sink.StartCapturingLogs();
744   LOG(INFO) << value;
745 }
746 
TEST(BoolLogFormatTest,True)747 TEST(BoolLogFormatTest, True) {
748   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
749 
750   const bool value = true;
751   auto comparison_stream = ComparisonStream();
752   comparison_stream << value;
753 
754   EXPECT_CALL(
755       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
756                             TextMessage(Eq("true")),
757                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
758                                                                str: "true"
759                                                              })pb")))));
760 
761   test_sink.StartCapturingLogs();
762   LOG(INFO) << value;
763 }
764 
TEST(BoolLogFormatTest,False)765 TEST(BoolLogFormatTest, False) {
766   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
767 
768   const bool value = false;
769   auto comparison_stream = ComparisonStream();
770   comparison_stream << value;
771 
772   EXPECT_CALL(
773       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
774                             TextMessage(Eq("false")),
775                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
776                                                                str: "false"
777                                                              })pb")))));
778 
779   test_sink.StartCapturingLogs();
780   LOG(INFO) << value;
781 }
782 
TEST(LogFormatTest,StringLiteral)783 TEST(LogFormatTest, StringLiteral) {
784   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
785 
786   auto comparison_stream = ComparisonStream();
787   comparison_stream << "value";
788 
789   EXPECT_CALL(test_sink,
790               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
791                          TextMessage(Eq("value")),
792                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
793                                                             literal: "value"
794                                                           })pb")))));
795 
796   test_sink.StartCapturingLogs();
797   LOG(INFO) << "value";
798 }
799 
TEST(LogFormatTest,CharArray)800 TEST(LogFormatTest, CharArray) {
801   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
802 
803   char value[] = "value";
804   auto comparison_stream = ComparisonStream();
805   comparison_stream << value;
806 
807   EXPECT_CALL(
808       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
809                             TextMessage(Eq("value")),
810                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
811                                                                str: "value"
812                                                              })pb")))));
813 
814   test_sink.StartCapturingLogs();
815   LOG(INFO) << value;
816 }
817 
818 class CustomClass {};
operator <<(std::ostream & os,const CustomClass &)819 std::ostream& operator<<(std::ostream& os, const CustomClass&) {
820   return os << "CustomClass{}";
821 }
822 
TEST(LogFormatTest,Custom)823 TEST(LogFormatTest, Custom) {
824   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
825 
826   CustomClass value;
827   auto comparison_stream = ComparisonStream();
828   comparison_stream << value;
829 
830   EXPECT_CALL(test_sink,
831               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
832                          TextMessage(Eq("CustomClass{}")),
833                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
834                                                             str: "CustomClass{}"
835                                                           })pb")))));
836   test_sink.StartCapturingLogs();
837   LOG(INFO) << value;
838 }
839 
840 class CustomClassNonCopyable {
841  public:
842   CustomClassNonCopyable() = default;
843   CustomClassNonCopyable(const CustomClassNonCopyable&) = delete;
844   CustomClassNonCopyable& operator=(const CustomClassNonCopyable&) = delete;
845 };
operator <<(std::ostream & os,const CustomClassNonCopyable &)846 std::ostream& operator<<(std::ostream& os, const CustomClassNonCopyable&) {
847   return os << "CustomClassNonCopyable{}";
848 }
849 
TEST(LogFormatTest,CustomNonCopyable)850 TEST(LogFormatTest, CustomNonCopyable) {
851   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
852 
853   CustomClassNonCopyable value;
854   auto comparison_stream = ComparisonStream();
855   comparison_stream << value;
856 
857   EXPECT_CALL(
858       test_sink,
859       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
860                  TextMessage(Eq("CustomClassNonCopyable{}")),
861                  ENCODED_MESSAGE(EqualsProto(
862                      R"pb(value { str: "CustomClassNonCopyable{}" })pb")))));
863 
864   test_sink.StartCapturingLogs();
865   LOG(INFO) << value;
866 }
867 
TEST(ManipulatorLogFormatTest,BoolAlphaTrue)868 TEST(ManipulatorLogFormatTest, BoolAlphaTrue) {
869   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
870 
871   const bool value = true;
872   auto comparison_stream = ComparisonStream();
873   comparison_stream << std::noboolalpha << value << " "  //
874                     << std::boolalpha << value << " "    //
875                     << std::noboolalpha << value;
876 
877   EXPECT_CALL(test_sink,
878               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
879                          TextMessage(Eq("1 true 1")),
880                          ENCODED_MESSAGE(EqualsProto(
881                              R"pb(value { str: "1" }
882                                   value { literal: " " }
883                                   value { str: "true" }
884                                   value { literal: " " }
885                                   value { str: "1" })pb")))));
886 
887   test_sink.StartCapturingLogs();
888   LOG(INFO) << std::noboolalpha << value << " "  //
889             << std::boolalpha << value << " "    //
890             << std::noboolalpha << value;
891 }
892 
TEST(ManipulatorLogFormatTest,BoolAlphaFalse)893 TEST(ManipulatorLogFormatTest, BoolAlphaFalse) {
894   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
895 
896   const bool value = false;
897   auto comparison_stream = ComparisonStream();
898   comparison_stream << std::noboolalpha << value << " "  //
899                     << std::boolalpha << value << " "    //
900                     << std::noboolalpha << value;
901 
902   EXPECT_CALL(test_sink,
903               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
904                          TextMessage(Eq("0 false 0")),
905                          ENCODED_MESSAGE(EqualsProto(
906                              R"pb(value { str: "0" }
907                                   value { literal: " " }
908                                   value { str: "false" }
909                                   value { literal: " " }
910                                   value { str: "0" })pb")))));
911 
912   test_sink.StartCapturingLogs();
913   LOG(INFO) << std::noboolalpha << value << " "  //
914             << std::boolalpha << value << " "    //
915             << std::noboolalpha << value;
916 }
917 
TEST(ManipulatorLogFormatTest,ShowPoint)918 TEST(ManipulatorLogFormatTest, ShowPoint) {
919   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
920 
921   const double value = 77.0;
922   auto comparison_stream = ComparisonStream();
923   comparison_stream << std::noshowpoint << value << " "  //
924                     << std::showpoint << value << " "    //
925                     << std::noshowpoint << value;
926 
927   EXPECT_CALL(
928       test_sink,
929       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
930                  TextMessage(Eq("77 77.0000 77")),
931                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
932                                                   value { literal: " " }
933                                                   value { str: "77.0000" }
934                                                   value { literal: " " }
935                                                   value { str: "77" })pb")))));
936 
937   test_sink.StartCapturingLogs();
938   LOG(INFO) << std::noshowpoint << value << " "  //
939             << std::showpoint << value << " "    //
940             << std::noshowpoint << value;
941 }
942 
TEST(ManipulatorLogFormatTest,ShowPos)943 TEST(ManipulatorLogFormatTest, ShowPos) {
944   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
945 
946   const int value = 77;
947   auto comparison_stream = ComparisonStream();
948   comparison_stream << std::noshowpos << value << " "  //
949                     << std::showpos << value << " "    //
950                     << std::noshowpos << value;
951 
952   EXPECT_CALL(
953       test_sink,
954       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
955                  TextMessage(Eq("77 +77 77")),
956                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
957                                                   value { literal: " " }
958                                                   value { str: "+77" }
959                                                   value { literal: " " }
960                                                   value { str: "77" })pb")))));
961 
962   test_sink.StartCapturingLogs();
963   LOG(INFO) << std::noshowpos << value << " "  //
964             << std::showpos << value << " "    //
965             << std::noshowpos << value;
966 }
967 
TEST(ManipulatorLogFormatTest,UppercaseFloat)968 TEST(ManipulatorLogFormatTest, UppercaseFloat) {
969   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
970 
971   const double value = 7.7e7;
972   auto comparison_stream = ComparisonStream();
973   comparison_stream << std::nouppercase << value << " "  //
974                     << std::uppercase << value << " "    //
975                     << std::nouppercase << value;
976 
977   EXPECT_CALL(test_sink,
978               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
979                          TextMessage(Eq("7.7e+07 7.7E+07 7.7e+07")),
980                          ENCODED_MESSAGE(EqualsProto(
981                              R"pb(value { str: "7.7e+07" }
982                                   value { literal: " " }
983                                   value { str: "7.7E+07" }
984                                   value { literal: " " }
985                                   value { str: "7.7e+07" })pb")))));
986 
987   test_sink.StartCapturingLogs();
988   LOG(INFO) << std::nouppercase << value << " "  //
989             << std::uppercase << value << " "    //
990             << std::nouppercase << value;
991 }
992 
TEST(ManipulatorLogFormatTest,Hex)993 TEST(ManipulatorLogFormatTest, Hex) {
994   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
995 
996   const int value = 0x77;
997   auto comparison_stream = ComparisonStream();
998   comparison_stream << std::hex << value;
999 
1000   EXPECT_CALL(
1001       test_sink, Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1002                             TextMessage(Eq("0x77")),
1003                             ENCODED_MESSAGE(EqualsProto(R"pb(value {
1004                                                                str: "0x77"
1005                                                              })pb")))));
1006   test_sink.StartCapturingLogs();
1007   LOG(INFO) << std::hex << value;
1008 }
1009 
TEST(ManipulatorLogFormatTest,Oct)1010 TEST(ManipulatorLogFormatTest, Oct) {
1011   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1012 
1013   const int value = 077;
1014   auto comparison_stream = ComparisonStream();
1015   comparison_stream << std::oct << value;
1016 
1017   EXPECT_CALL(
1018       test_sink,
1019       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1020                  TextMessage(Eq("077")),
1021                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "077" })pb")))));
1022 
1023   test_sink.StartCapturingLogs();
1024   LOG(INFO) << std::oct << value;
1025 }
1026 
TEST(ManipulatorLogFormatTest,Dec)1027 TEST(ManipulatorLogFormatTest, Dec) {
1028   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1029 
1030   const int value = 77;
1031   auto comparison_stream = ComparisonStream();
1032   comparison_stream << std::hex << std::dec << value;
1033 
1034   EXPECT_CALL(
1035       test_sink,
1036       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1037                  TextMessage(Eq("77")),
1038                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" })pb")))));
1039 
1040   test_sink.StartCapturingLogs();
1041   LOG(INFO) << std::hex << std::dec << value;
1042 }
1043 
TEST(ManipulatorLogFormatTest,ShowbaseHex)1044 TEST(ManipulatorLogFormatTest, ShowbaseHex) {
1045   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1046 
1047   const int value = 0x77;
1048   auto comparison_stream = ComparisonStream();
1049   comparison_stream << std::hex                         //
1050                     << std::noshowbase << value << " "  //
1051                     << std::showbase << value << " "    //
1052                     << std::noshowbase << value;
1053 
1054   EXPECT_CALL(
1055       test_sink,
1056       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1057                  TextMessage(Eq("77 0x77 77")),
1058                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
1059                                                   value { literal: " " }
1060                                                   value { str: "0x77" }
1061                                                   value { literal: " " }
1062                                                   value { str: "77" })pb")))));
1063 
1064   test_sink.StartCapturingLogs();
1065   LOG(INFO) << std::hex                         //
1066             << std::noshowbase << value << " "  //
1067             << std::showbase << value << " "    //
1068             << std::noshowbase << value;
1069 }
1070 
TEST(ManipulatorLogFormatTest,ShowbaseOct)1071 TEST(ManipulatorLogFormatTest, ShowbaseOct) {
1072   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1073 
1074   const int value = 077;
1075   auto comparison_stream = ComparisonStream();
1076   comparison_stream << std::oct                         //
1077                     << std::noshowbase << value << " "  //
1078                     << std::showbase << value << " "    //
1079                     << std::noshowbase << value;
1080 
1081   EXPECT_CALL(
1082       test_sink,
1083       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1084                  TextMessage(Eq("77 077 77")),
1085                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" }
1086                                                   value { literal: " " }
1087                                                   value { str: "077" }
1088                                                   value { literal: " " }
1089                                                   value { str: "77" })pb")))));
1090 
1091   test_sink.StartCapturingLogs();
1092   LOG(INFO) << std::oct                         //
1093             << std::noshowbase << value << " "  //
1094             << std::showbase << value << " "    //
1095             << std::noshowbase << value;
1096 }
1097 
TEST(ManipulatorLogFormatTest,UppercaseHex)1098 TEST(ManipulatorLogFormatTest, UppercaseHex) {
1099   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1100 
1101   const int value = 0xbeef;
1102   auto comparison_stream = ComparisonStream();
1103   comparison_stream                        //
1104       << std::hex                          //
1105       << std::nouppercase << value << " "  //
1106       << std::uppercase << value << " "    //
1107       << std::nouppercase << value;
1108 
1109   EXPECT_CALL(test_sink,
1110               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1111                          TextMessage(Eq("0xbeef 0XBEEF 0xbeef")),
1112                          ENCODED_MESSAGE(EqualsProto(
1113                              R"pb(value { str: "0xbeef" }
1114                                   value { literal: " " }
1115                                   value { str: "0XBEEF" }
1116                                   value { literal: " " }
1117                                   value { str: "0xbeef" })pb")))));
1118 
1119   test_sink.StartCapturingLogs();
1120   LOG(INFO) << std::hex                          //
1121             << std::nouppercase << value << " "  //
1122             << std::uppercase << value << " "    //
1123             << std::nouppercase << value;
1124 }
1125 
TEST(ManipulatorLogFormatTest,FixedFloat)1126 TEST(ManipulatorLogFormatTest, FixedFloat) {
1127   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1128 
1129   const double value = 7.7e7;
1130   auto comparison_stream = ComparisonStream();
1131   comparison_stream << std::fixed << value;
1132 
1133   EXPECT_CALL(
1134       test_sink,
1135       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1136                  TextMessage(Eq("77000000.000000")),
1137                  ENCODED_MESSAGE(EqualsProto(R"pb(value {
1138                                                     str: "77000000.000000"
1139                                                   })pb")))));
1140 
1141   test_sink.StartCapturingLogs();
1142   LOG(INFO) << std::fixed << value;
1143 }
1144 
TEST(ManipulatorLogFormatTest,ScientificFloat)1145 TEST(ManipulatorLogFormatTest, ScientificFloat) {
1146   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1147 
1148   const double value = 7.7e7;
1149   auto comparison_stream = ComparisonStream();
1150   comparison_stream << std::scientific << value;
1151 
1152   EXPECT_CALL(test_sink,
1153               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1154                          TextMessage(Eq("7.700000e+07")),
1155                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1156                                                             str: "7.700000e+07"
1157                                                           })pb")))));
1158 
1159   test_sink.StartCapturingLogs();
1160   LOG(INFO) << std::scientific << value;
1161 }
1162 
1163 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
1164 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the
1165 // C++ standard library implements it correctly (by forwarding to printf).
1166 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
1167 // libstdc++ shipped C++11 support without `std::hexfloat`.
1168 #else
TEST(ManipulatorLogFormatTest,FixedAndScientificFloat)1169 TEST(ManipulatorLogFormatTest, FixedAndScientificFloat) {
1170   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1171 
1172   const double value = 7.7e7;
1173   auto comparison_stream = ComparisonStream();
1174   comparison_stream << std::setiosflags(std::ios_base::scientific |
1175                                         std::ios_base::fixed)
1176                     << value;
1177 
1178   EXPECT_CALL(
1179       test_sink,
1180       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1181                  TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
1182                                    Eq("0x1.25bb500000000p+26"))),
1183                  ENCODED_MESSAGE(EqualsProto(R"pb(
1184                    value { str: "0x1.25bb5p+26" })pb")))));
1185 
1186   test_sink.StartCapturingLogs();
1187 
1188   // This combination should mean the same thing as `std::hexfloat`.
1189   LOG(INFO) << std::setiosflags(std::ios_base::scientific |
1190                                 std::ios_base::fixed)
1191             << value;
1192 }
1193 #endif
1194 
1195 #if defined(__BIONIC__) && (!defined(__ANDROID_API__) || __ANDROID_API__ < 22)
1196 // Bionic doesn't support `%a` until API 22, so this prints 'a' even if the C++
1197 // standard library supports `std::hexfloat` (by forwarding to printf).
1198 #elif defined(__GLIBCXX__) && __cplusplus < 201402L
1199 // libstdc++ shipped C++11 support without `std::hexfloat`.
1200 #else
TEST(ManipulatorLogFormatTest,HexfloatFloat)1201 TEST(ManipulatorLogFormatTest, HexfloatFloat) {
1202   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1203 
1204   const double value = 7.7e7;
1205   auto comparison_stream = ComparisonStream();
1206   comparison_stream << std::hexfloat << value;
1207 
1208   EXPECT_CALL(
1209       test_sink,
1210       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1211                  TextMessage(AnyOf(Eq("0x1.25bb50p+26"), Eq("0x1.25bb5p+26"),
1212                                    Eq("0x1.25bb500000000p+26"))),
1213                  ENCODED_MESSAGE(EqualsProto(R"pb(
1214                    value { str: "0x1.25bb5p+26" })pb")))));
1215 
1216   test_sink.StartCapturingLogs();
1217   LOG(INFO) << std::hexfloat << value;
1218 }
1219 #endif
1220 
TEST(ManipulatorLogFormatTest,DefaultFloatFloat)1221 TEST(ManipulatorLogFormatTest, DefaultFloatFloat) {
1222   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1223 
1224   const double value = 7.7e7;
1225   auto comparison_stream = ComparisonStream();
1226   comparison_stream << std::hexfloat << std::defaultfloat << value;
1227 
1228   EXPECT_CALL(test_sink,
1229               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1230                          TextMessage(Eq("7.7e+07")),
1231                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1232                                                             str: "7.7e+07"
1233                                                           })pb")))));
1234 
1235   test_sink.StartCapturingLogs();
1236   LOG(INFO) << std::hexfloat << std::defaultfloat << value;
1237 }
1238 
TEST(ManipulatorLogFormatTest,Ends)1239 TEST(ManipulatorLogFormatTest, Ends) {
1240   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1241 
1242   auto comparison_stream = ComparisonStream();
1243   comparison_stream << std::ends;
1244 
1245   EXPECT_CALL(
1246       test_sink,
1247       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1248                  TextMessage(Eq(absl::string_view("\0", 1))),
1249                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "\0" })pb")))));
1250 
1251   test_sink.StartCapturingLogs();
1252   LOG(INFO) << std::ends;
1253 }
1254 
TEST(ManipulatorLogFormatTest,Endl)1255 TEST(ManipulatorLogFormatTest, Endl) {
1256   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1257 
1258   auto comparison_stream = ComparisonStream();
1259   comparison_stream << std::endl;
1260 
1261   EXPECT_CALL(test_sink,
1262               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1263                          TextMessage(Eq("\n")))));
1264 
1265   test_sink.StartCapturingLogs();
1266   LOG(INFO) << std::endl;
1267 }
1268 
TEST(ManipulatorLogFormatTest,SetIosFlags)1269 TEST(ManipulatorLogFormatTest, SetIosFlags) {
1270   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1271 
1272   const int value = 0x77;
1273   auto comparison_stream = ComparisonStream();
1274   comparison_stream << std::resetiosflags(std::ios_base::basefield)
1275                     << std::setiosflags(std::ios_base::hex) << value << " "  //
1276                     << std::resetiosflags(std::ios_base::basefield)
1277                     << std::setiosflags(std::ios_base::dec) << value;
1278 
1279   EXPECT_CALL(
1280       test_sink,
1281       Send(AllOf(
1282           TextMessage(MatchesOstream(comparison_stream)),
1283           TextMessage(Eq("0x77 119")),
1284           // `std::setiosflags` and `std::resetiosflags` aren't manipulators.
1285           // We're unable to distinguish their return type(s) from arbitrary
1286           // user-defined types and thus don't suppress the empty str value.
1287           ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "0x77" }
1288                                            value { literal: " " }
1289                                            value { str: "119" }
1290           )pb")))));
1291 
1292   test_sink.StartCapturingLogs();
1293   LOG(INFO) << std::resetiosflags(std::ios_base::basefield)
1294             << std::setiosflags(std::ios_base::hex) << value << " "  //
1295             << std::resetiosflags(std::ios_base::basefield)
1296             << std::setiosflags(std::ios_base::dec) << value;
1297 }
1298 
TEST(ManipulatorLogFormatTest,SetBase)1299 TEST(ManipulatorLogFormatTest, SetBase) {
1300   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1301 
1302   const int value = 0x77;
1303   auto comparison_stream = ComparisonStream();
1304   comparison_stream << std::setbase(16) << value << " "  //
1305                     << std::setbase(0) << value;
1306 
1307   EXPECT_CALL(
1308       test_sink,
1309       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1310                  TextMessage(Eq("0x77 119")),
1311                  // `std::setbase` isn't a manipulator.  We're unable to
1312                  // distinguish its return type from arbitrary user-defined
1313                  // types and thus don't suppress the empty str value.
1314                  ENCODED_MESSAGE(EqualsProto(
1315                      R"pb(value { str: "0x77" }
1316                           value { literal: " " }
1317                           value { str: "119" })pb")))));
1318 
1319   test_sink.StartCapturingLogs();
1320   LOG(INFO) << std::setbase(16) << value << " "  //
1321             << std::setbase(0) << value;
1322 }
1323 
TEST(ManipulatorLogFormatTest,SetPrecision)1324 TEST(ManipulatorLogFormatTest, SetPrecision) {
1325   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1326 
1327   const double value = 6.022140857e23;
1328   auto comparison_stream = ComparisonStream();
1329   comparison_stream << std::setprecision(4) << value;
1330 
1331   EXPECT_CALL(
1332       test_sink,
1333       Send(AllOf(
1334           TextMessage(MatchesOstream(comparison_stream)),
1335           TextMessage(Eq("6.022e+23")),
1336           // `std::setprecision` isn't a manipulator.  We're unable to
1337           // distinguish its return type from arbitrary user-defined
1338           // types and thus don't suppress the empty str value.
1339           ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "6.022e+23" })pb")))));
1340 
1341   test_sink.StartCapturingLogs();
1342   LOG(INFO) << std::setprecision(4) << value;
1343 }
1344 
TEST(ManipulatorLogFormatTest,SetPrecisionOverflow)1345 TEST(ManipulatorLogFormatTest, SetPrecisionOverflow) {
1346   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1347 
1348   const double value = 6.022140857e23;
1349   auto comparison_stream = ComparisonStream();
1350   comparison_stream << std::setprecision(200) << value;
1351 
1352   EXPECT_CALL(
1353       test_sink,
1354       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1355                  TextMessage(Eq("602214085700000015187968")),
1356                  ENCODED_MESSAGE(EqualsProto(
1357                      R"pb(value { str: "602214085700000015187968" })pb")))));
1358 
1359   test_sink.StartCapturingLogs();
1360   LOG(INFO) << std::setprecision(200) << value;
1361 }
1362 
TEST(ManipulatorLogFormatTest,SetW)1363 TEST(ManipulatorLogFormatTest, SetW) {
1364   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1365 
1366   const int value = 77;
1367   auto comparison_stream = ComparisonStream();
1368   comparison_stream << std::setw(8) << value;
1369 
1370   EXPECT_CALL(
1371       test_sink,
1372       Send(AllOf(
1373           TextMessage(MatchesOstream(comparison_stream)),
1374           TextMessage(Eq("      77")),
1375           // `std::setw` isn't a manipulator.  We're unable to
1376           // distinguish its return type from arbitrary user-defined
1377           // types and thus don't suppress the empty str value.
1378           ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "      77" })pb")))));
1379 
1380   test_sink.StartCapturingLogs();
1381   LOG(INFO) << std::setw(8) << value;
1382 }
1383 
TEST(ManipulatorLogFormatTest,Left)1384 TEST(ManipulatorLogFormatTest, Left) {
1385   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1386 
1387   const int value = -77;
1388   auto comparison_stream = ComparisonStream();
1389   comparison_stream << std::left << std::setw(8) << value;
1390 
1391   EXPECT_CALL(test_sink,
1392               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1393                          TextMessage(Eq("-77     ")),
1394                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1395                                                             str: "-77     "
1396                                                           })pb")))));
1397 
1398   test_sink.StartCapturingLogs();
1399   LOG(INFO) << std::left << std::setw(8) << value;
1400 }
1401 
TEST(ManipulatorLogFormatTest,Right)1402 TEST(ManipulatorLogFormatTest, Right) {
1403   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1404 
1405   const int value = -77;
1406   auto comparison_stream = ComparisonStream();
1407   comparison_stream << std::right << std::setw(8) << value;
1408 
1409   EXPECT_CALL(test_sink,
1410               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1411                          TextMessage(Eq("     -77")),
1412                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1413                                                             str: "     -77"
1414                                                           })pb")))));
1415 
1416   test_sink.StartCapturingLogs();
1417   LOG(INFO) << std::right << std::setw(8) << value;
1418 }
1419 
TEST(ManipulatorLogFormatTest,Internal)1420 TEST(ManipulatorLogFormatTest, Internal) {
1421   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1422 
1423   const int value = -77;
1424   auto comparison_stream = ComparisonStream();
1425   comparison_stream << std::internal << std::setw(8) << value;
1426 
1427   EXPECT_CALL(test_sink,
1428               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1429                          TextMessage(Eq("-     77")),
1430                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1431                                                             str: "-     77"
1432                                                           })pb")))));
1433 
1434   test_sink.StartCapturingLogs();
1435   LOG(INFO) << std::internal << std::setw(8) << value;
1436 }
1437 
TEST(ManipulatorLogFormatTest,SetFill)1438 TEST(ManipulatorLogFormatTest, SetFill) {
1439   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1440 
1441   const int value = 77;
1442   auto comparison_stream = ComparisonStream();
1443   comparison_stream << std::setfill('0') << std::setw(8) << value;
1444 
1445   EXPECT_CALL(test_sink,
1446               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1447                          TextMessage(Eq("00000077")),
1448                          // `std::setfill` isn't a manipulator.  We're
1449                          // unable to distinguish its return
1450                          // type from arbitrary user-defined types and
1451                          // thus don't suppress the empty str value.
1452                          ENCODED_MESSAGE(EqualsProto(R"pb(value {
1453                                                             str: "00000077"
1454                                                           })pb")))));
1455 
1456   test_sink.StartCapturingLogs();
1457   LOG(INFO) << std::setfill('0') << std::setw(8) << value;
1458 }
1459 
1460 class FromCustomClass {};
operator <<(std::ostream & os,const FromCustomClass &)1461 std::ostream& operator<<(std::ostream& os, const FromCustomClass&) {
1462   return os << "FromCustomClass{}" << std::hex;
1463 }
1464 
TEST(ManipulatorLogFormatTest,FromCustom)1465 TEST(ManipulatorLogFormatTest, FromCustom) {
1466   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1467 
1468   FromCustomClass value;
1469   auto comparison_stream = ComparisonStream();
1470   comparison_stream << value << " " << 0x77;
1471 
1472   EXPECT_CALL(test_sink,
1473               Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1474                          TextMessage(Eq("FromCustomClass{} 0x77")),
1475                          ENCODED_MESSAGE(EqualsProto(
1476                              R"pb(value { str: "FromCustomClass{}" }
1477                                   value { literal: " " }
1478                                   value { str: "0x77" })pb")))));
1479 
1480   test_sink.StartCapturingLogs();
1481   LOG(INFO) << value << " " << 0x77;
1482 }
1483 
1484 class StreamsNothing {};
operator <<(std::ostream & os,const StreamsNothing &)1485 std::ostream& operator<<(std::ostream& os, const StreamsNothing&) { return os; }
1486 
TEST(ManipulatorLogFormatTest,CustomClassStreamsNothing)1487 TEST(ManipulatorLogFormatTest, CustomClassStreamsNothing) {
1488   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1489 
1490   StreamsNothing value;
1491   auto comparison_stream = ComparisonStream();
1492   comparison_stream << value << 77;
1493 
1494   EXPECT_CALL(
1495       test_sink,
1496       Send(AllOf(TextMessage(MatchesOstream(comparison_stream)),
1497                  TextMessage(Eq("77")),
1498                  ENCODED_MESSAGE(EqualsProto(R"pb(value { str: "77" })pb")))));
1499 
1500   test_sink.StartCapturingLogs();
1501   LOG(INFO) << value << 77;
1502 }
1503 
1504 // Tests that verify the behavior when more data are streamed into a `LOG`
1505 // statement than fit in the buffer.
1506 // Structured logging scenario is tested in other unit tests since the output is
1507 // significantly different.
TEST(OverflowTest,TruncatesStrings)1508 TEST(OverflowTest, TruncatesStrings) {
1509   absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
1510 
1511   // This message is too long and should be truncated to some unspecified size
1512   // no greater than the buffer size but not too much less either. It should be
1513   // truncated rather than discarded.
1514   constexpr size_t buffer_size = 15000;
1515 
1516   EXPECT_CALL(test_sink,
1517               Send(TextMessage(
1518                   AllOf(SizeIs(AllOf(Ge(buffer_size - 256), Le(buffer_size))),
1519                         Each(Eq('x'))))));
1520 
1521   test_sink.StartCapturingLogs();
1522   LOG(INFO) << std::string(2 * buffer_size, 'x');
1523 }
1524 
1525 }  // namespace
1526