]>
Commit | Line | Data |
---|---|---|
31f18b77 FG |
1 | // Copyright 2007, Google Inc. |
2 | // All rights reserved. | |
3 | // | |
4 | // Redistribution and use in source and binary forms, with or without | |
5 | // modification, are permitted provided that the following conditions are | |
6 | // met: | |
7 | // | |
8 | // * Redistributions of source code must retain the above copyright | |
9 | // notice, this list of conditions and the following disclaimer. | |
10 | // * Redistributions in binary form must reproduce the above | |
11 | // copyright notice, this list of conditions and the following disclaimer | |
12 | // in the documentation and/or other materials provided with the | |
13 | // distribution. | |
14 | // * Neither the name of Google Inc. nor the names of its | |
15 | // contributors may be used to endorse or promote products derived from | |
16 | // this software without specific prior written permission. | |
17 | // | |
18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31f18b77 | 29 | |
1e59de90 TL |
30 | |
31 | // Google Test - The Google C++ Testing and Mocking Framework | |
31f18b77 FG |
32 | // |
33 | // This file tests the universal value printer. | |
34 | ||
31f18b77 | 35 | #include <ctype.h> |
31f18b77 FG |
36 | #include <string.h> |
37 | #include <algorithm> | |
1e59de90 | 38 | #include <cstdint> |
31f18b77 | 39 | #include <deque> |
1e59de90 TL |
40 | #include <forward_list> |
41 | #include <limits> | |
31f18b77 FG |
42 | #include <list> |
43 | #include <map> | |
44 | #include <set> | |
45 | #include <sstream> | |
46 | #include <string> | |
1e59de90 TL |
47 | #include <unordered_map> |
48 | #include <unordered_set> | |
31f18b77 FG |
49 | #include <utility> |
50 | #include <vector> | |
51 | ||
1e59de90 | 52 | #include "gtest/gtest-printers.h" |
31f18b77 FG |
53 | #include "gtest/gtest.h" |
54 | ||
31f18b77 FG |
55 | // Some user-defined types for testing the universal value printer. |
56 | ||
57 | // An anonymous enum type. | |
58 | enum AnonymousEnum { | |
59 | kAE1 = -1, | |
60 | kAE2 = 1 | |
61 | }; | |
62 | ||
63 | // An enum without a user-defined printer. | |
64 | enum EnumWithoutPrinter { | |
65 | kEWP1 = -2, | |
66 | kEWP2 = 42 | |
67 | }; | |
68 | ||
69 | // An enum with a << operator. | |
70 | enum EnumWithStreaming { | |
71 | kEWS1 = 10 | |
72 | }; | |
73 | ||
74 | std::ostream& operator<<(std::ostream& os, EnumWithStreaming e) { | |
75 | return os << (e == kEWS1 ? "kEWS1" : "invalid"); | |
76 | } | |
77 | ||
78 | // An enum with a PrintTo() function. | |
79 | enum EnumWithPrintTo { | |
80 | kEWPT1 = 1 | |
81 | }; | |
82 | ||
83 | void PrintTo(EnumWithPrintTo e, std::ostream* os) { | |
84 | *os << (e == kEWPT1 ? "kEWPT1" : "invalid"); | |
85 | } | |
86 | ||
87 | // A class implicitly convertible to BiggestInt. | |
88 | class BiggestIntConvertible { | |
89 | public: | |
90 | operator ::testing::internal::BiggestInt() const { return 42; } | |
91 | }; | |
92 | ||
1e59de90 TL |
93 | // A parent class with two child classes. The parent and one of the kids have |
94 | // stream operators. | |
95 | class ParentClass {}; | |
96 | class ChildClassWithStreamOperator : public ParentClass {}; | |
97 | class ChildClassWithoutStreamOperator : public ParentClass {}; | |
98 | static void operator<<(std::ostream& os, const ParentClass&) { | |
99 | os << "ParentClass"; | |
100 | } | |
101 | static void operator<<(std::ostream& os, const ChildClassWithStreamOperator&) { | |
102 | os << "ChildClassWithStreamOperator"; | |
103 | } | |
104 | ||
31f18b77 FG |
105 | // A user-defined unprintable class template in the global namespace. |
106 | template <typename T> | |
107 | class UnprintableTemplateInGlobal { | |
108 | public: | |
109 | UnprintableTemplateInGlobal() : value_() {} | |
110 | private: | |
111 | T value_; | |
112 | }; | |
113 | ||
114 | // A user-defined streamable type in the global namespace. | |
115 | class StreamableInGlobal { | |
116 | public: | |
117 | virtual ~StreamableInGlobal() {} | |
118 | }; | |
119 | ||
120 | inline void operator<<(::std::ostream& os, const StreamableInGlobal& /* x */) { | |
121 | os << "StreamableInGlobal"; | |
122 | } | |
123 | ||
124 | void operator<<(::std::ostream& os, const StreamableInGlobal* /* x */) { | |
125 | os << "StreamableInGlobal*"; | |
126 | } | |
127 | ||
128 | namespace foo { | |
129 | ||
130 | // A user-defined unprintable type in a user namespace. | |
131 | class UnprintableInFoo { | |
132 | public: | |
133 | UnprintableInFoo() : z_(0) { memcpy(xy_, "\xEF\x12\x0\x0\x34\xAB\x0\x0", 8); } | |
134 | double z() const { return z_; } | |
135 | private: | |
136 | char xy_[8]; | |
137 | double z_; | |
138 | }; | |
139 | ||
140 | // A user-defined printable type in a user-chosen namespace. | |
141 | struct PrintableViaPrintTo { | |
142 | PrintableViaPrintTo() : value() {} | |
143 | int value; | |
144 | }; | |
145 | ||
146 | void PrintTo(const PrintableViaPrintTo& x, ::std::ostream* os) { | |
147 | *os << "PrintableViaPrintTo: " << x.value; | |
148 | } | |
149 | ||
150 | // A type with a user-defined << for printing its pointer. | |
151 | struct PointerPrintable { | |
152 | }; | |
153 | ||
154 | ::std::ostream& operator<<(::std::ostream& os, | |
155 | const PointerPrintable* /* x */) { | |
156 | return os << "PointerPrintable*"; | |
157 | } | |
158 | ||
159 | // A user-defined printable class template in a user-chosen namespace. | |
160 | template <typename T> | |
161 | class PrintableViaPrintToTemplate { | |
162 | public: | |
163 | explicit PrintableViaPrintToTemplate(const T& a_value) : value_(a_value) {} | |
164 | ||
165 | const T& value() const { return value_; } | |
166 | private: | |
167 | T value_; | |
168 | }; | |
169 | ||
170 | template <typename T> | |
171 | void PrintTo(const PrintableViaPrintToTemplate<T>& x, ::std::ostream* os) { | |
172 | *os << "PrintableViaPrintToTemplate: " << x.value(); | |
173 | } | |
174 | ||
175 | // A user-defined streamable class template in a user namespace. | |
176 | template <typename T> | |
177 | class StreamableTemplateInFoo { | |
178 | public: | |
179 | StreamableTemplateInFoo() : value_() {} | |
180 | ||
181 | const T& value() const { return value_; } | |
182 | private: | |
183 | T value_; | |
184 | }; | |
185 | ||
186 | template <typename T> | |
187 | inline ::std::ostream& operator<<(::std::ostream& os, | |
188 | const StreamableTemplateInFoo<T>& x) { | |
189 | return os << "StreamableTemplateInFoo: " << x.value(); | |
190 | } | |
191 | ||
1e59de90 TL |
192 | // A user-defined streamable type in a user namespace whose operator<< is |
193 | // templated on the type of the output stream. | |
194 | struct TemplatedStreamableInFoo {}; | |
195 | ||
196 | template <typename OutputStream> | |
197 | OutputStream& operator<<(OutputStream& os, | |
198 | const TemplatedStreamableInFoo& /*ts*/) { | |
199 | os << "TemplatedStreamableInFoo"; | |
200 | return os; | |
201 | } | |
202 | ||
203 | // A user-defined streamable but recursivly-defined container type in | |
204 | // a user namespace, it mimics therefore std::filesystem::path or | |
205 | // boost::filesystem::path. | |
206 | class PathLike { | |
207 | public: | |
208 | struct iterator { | |
209 | typedef PathLike value_type; | |
210 | ||
211 | iterator& operator++(); | |
212 | PathLike& operator*(); | |
213 | }; | |
214 | ||
215 | using value_type = char; | |
216 | using const_iterator = iterator; | |
217 | ||
218 | PathLike() {} | |
219 | ||
220 | iterator begin() const { return iterator(); } | |
221 | iterator end() const { return iterator(); } | |
222 | ||
223 | friend ::std::ostream& operator<<(::std::ostream& os, const PathLike&) { | |
224 | return os << "Streamable-PathLike"; | |
225 | } | |
226 | }; | |
227 | ||
31f18b77 FG |
228 | } // namespace foo |
229 | ||
230 | namespace testing { | |
231 | namespace gtest_printers_test { | |
232 | ||
233 | using ::std::deque; | |
234 | using ::std::list; | |
235 | using ::std::make_pair; | |
236 | using ::std::map; | |
237 | using ::std::multimap; | |
238 | using ::std::multiset; | |
239 | using ::std::pair; | |
240 | using ::std::set; | |
241 | using ::std::vector; | |
242 | using ::testing::PrintToString; | |
243 | using ::testing::internal::FormatForComparisonFailureMessage; | |
244 | using ::testing::internal::ImplicitCast_; | |
245 | using ::testing::internal::NativeArray; | |
31f18b77 FG |
246 | using ::testing::internal::RelationToSourceReference; |
247 | using ::testing::internal::Strings; | |
248 | using ::testing::internal::UniversalPrint; | |
249 | using ::testing::internal::UniversalPrinter; | |
250 | using ::testing::internal::UniversalTersePrint; | |
251 | using ::testing::internal::UniversalTersePrintTupleFieldsToStrings; | |
31f18b77 FG |
252 | |
253 | // Prints a value to a string using the universal value printer. This | |
254 | // is a helper for testing UniversalPrinter<T>::Print() for various types. | |
255 | template <typename T> | |
1e59de90 | 256 | std::string Print(const T& value) { |
31f18b77 FG |
257 | ::std::stringstream ss; |
258 | UniversalPrinter<T>::Print(value, &ss); | |
259 | return ss.str(); | |
260 | } | |
261 | ||
262 | // Prints a value passed by reference to a string, using the universal | |
263 | // value printer. This is a helper for testing | |
264 | // UniversalPrinter<T&>::Print() for various types. | |
265 | template <typename T> | |
1e59de90 | 266 | std::string PrintByRef(const T& value) { |
31f18b77 FG |
267 | ::std::stringstream ss; |
268 | UniversalPrinter<T&>::Print(value, &ss); | |
269 | return ss.str(); | |
270 | } | |
271 | ||
272 | // Tests printing various enum types. | |
273 | ||
274 | TEST(PrintEnumTest, AnonymousEnum) { | |
275 | EXPECT_EQ("-1", Print(kAE1)); | |
276 | EXPECT_EQ("1", Print(kAE2)); | |
277 | } | |
278 | ||
279 | TEST(PrintEnumTest, EnumWithoutPrinter) { | |
280 | EXPECT_EQ("-2", Print(kEWP1)); | |
281 | EXPECT_EQ("42", Print(kEWP2)); | |
282 | } | |
283 | ||
284 | TEST(PrintEnumTest, EnumWithStreaming) { | |
285 | EXPECT_EQ("kEWS1", Print(kEWS1)); | |
286 | EXPECT_EQ("invalid", Print(static_cast<EnumWithStreaming>(0))); | |
287 | } | |
288 | ||
289 | TEST(PrintEnumTest, EnumWithPrintTo) { | |
290 | EXPECT_EQ("kEWPT1", Print(kEWPT1)); | |
291 | EXPECT_EQ("invalid", Print(static_cast<EnumWithPrintTo>(0))); | |
292 | } | |
293 | ||
294 | // Tests printing a class implicitly convertible to BiggestInt. | |
295 | ||
296 | TEST(PrintClassTest, BiggestIntConvertible) { | |
297 | EXPECT_EQ("42", Print(BiggestIntConvertible())); | |
298 | } | |
299 | ||
300 | // Tests printing various char types. | |
301 | ||
302 | // char. | |
303 | TEST(PrintCharTest, PlainChar) { | |
304 | EXPECT_EQ("'\\0'", Print('\0')); | |
305 | EXPECT_EQ("'\\'' (39, 0x27)", Print('\'')); | |
306 | EXPECT_EQ("'\"' (34, 0x22)", Print('"')); | |
307 | EXPECT_EQ("'?' (63, 0x3F)", Print('?')); | |
308 | EXPECT_EQ("'\\\\' (92, 0x5C)", Print('\\')); | |
309 | EXPECT_EQ("'\\a' (7)", Print('\a')); | |
310 | EXPECT_EQ("'\\b' (8)", Print('\b')); | |
311 | EXPECT_EQ("'\\f' (12, 0xC)", Print('\f')); | |
312 | EXPECT_EQ("'\\n' (10, 0xA)", Print('\n')); | |
313 | EXPECT_EQ("'\\r' (13, 0xD)", Print('\r')); | |
314 | EXPECT_EQ("'\\t' (9)", Print('\t')); | |
315 | EXPECT_EQ("'\\v' (11, 0xB)", Print('\v')); | |
316 | EXPECT_EQ("'\\x7F' (127)", Print('\x7F')); | |
317 | EXPECT_EQ("'\\xFF' (255)", Print('\xFF')); | |
318 | EXPECT_EQ("' ' (32, 0x20)", Print(' ')); | |
319 | EXPECT_EQ("'a' (97, 0x61)", Print('a')); | |
320 | } | |
321 | ||
322 | // signed char. | |
323 | TEST(PrintCharTest, SignedChar) { | |
324 | EXPECT_EQ("'\\0'", Print(static_cast<signed char>('\0'))); | |
325 | EXPECT_EQ("'\\xCE' (-50)", | |
326 | Print(static_cast<signed char>(-50))); | |
327 | } | |
328 | ||
329 | // unsigned char. | |
330 | TEST(PrintCharTest, UnsignedChar) { | |
331 | EXPECT_EQ("'\\0'", Print(static_cast<unsigned char>('\0'))); | |
332 | EXPECT_EQ("'b' (98, 0x62)", | |
333 | Print(static_cast<unsigned char>('b'))); | |
334 | } | |
335 | ||
1e59de90 TL |
336 | TEST(PrintCharTest, Char16) { |
337 | EXPECT_EQ("U+0041", Print(u'A')); | |
338 | } | |
339 | ||
340 | TEST(PrintCharTest, Char32) { | |
341 | EXPECT_EQ("U+0041", Print(U'A')); | |
342 | } | |
343 | ||
344 | #ifdef __cpp_char8_t | |
345 | TEST(PrintCharTest, Char8) { | |
346 | EXPECT_EQ("U+0041", Print(u8'A')); | |
347 | } | |
348 | #endif | |
349 | ||
31f18b77 FG |
350 | // Tests printing other simple, built-in types. |
351 | ||
352 | // bool. | |
353 | TEST(PrintBuiltInTypeTest, Bool) { | |
354 | EXPECT_EQ("false", Print(false)); | |
355 | EXPECT_EQ("true", Print(true)); | |
356 | } | |
357 | ||
358 | // wchar_t. | |
359 | TEST(PrintBuiltInTypeTest, Wchar_t) { | |
360 | EXPECT_EQ("L'\\0'", Print(L'\0')); | |
361 | EXPECT_EQ("L'\\'' (39, 0x27)", Print(L'\'')); | |
362 | EXPECT_EQ("L'\"' (34, 0x22)", Print(L'"')); | |
363 | EXPECT_EQ("L'?' (63, 0x3F)", Print(L'?')); | |
364 | EXPECT_EQ("L'\\\\' (92, 0x5C)", Print(L'\\')); | |
365 | EXPECT_EQ("L'\\a' (7)", Print(L'\a')); | |
366 | EXPECT_EQ("L'\\b' (8)", Print(L'\b')); | |
367 | EXPECT_EQ("L'\\f' (12, 0xC)", Print(L'\f')); | |
368 | EXPECT_EQ("L'\\n' (10, 0xA)", Print(L'\n')); | |
369 | EXPECT_EQ("L'\\r' (13, 0xD)", Print(L'\r')); | |
370 | EXPECT_EQ("L'\\t' (9)", Print(L'\t')); | |
371 | EXPECT_EQ("L'\\v' (11, 0xB)", Print(L'\v')); | |
372 | EXPECT_EQ("L'\\x7F' (127)", Print(L'\x7F')); | |
373 | EXPECT_EQ("L'\\xFF' (255)", Print(L'\xFF')); | |
374 | EXPECT_EQ("L' ' (32, 0x20)", Print(L' ')); | |
375 | EXPECT_EQ("L'a' (97, 0x61)", Print(L'a')); | |
376 | EXPECT_EQ("L'\\x576' (1398)", Print(static_cast<wchar_t>(0x576))); | |
377 | EXPECT_EQ("L'\\xC74D' (51021)", Print(static_cast<wchar_t>(0xC74D))); | |
378 | } | |
379 | ||
1e59de90 | 380 | // Test that int64_t provides more storage than wchar_t. |
31f18b77 | 381 | TEST(PrintTypeSizeTest, Wchar_t) { |
1e59de90 | 382 | EXPECT_LT(sizeof(wchar_t), sizeof(int64_t)); |
31f18b77 FG |
383 | } |
384 | ||
385 | // Various integer types. | |
386 | TEST(PrintBuiltInTypeTest, Integer) { | |
387 | EXPECT_EQ("'\\xFF' (255)", Print(static_cast<unsigned char>(255))); // uint8 | |
388 | EXPECT_EQ("'\\x80' (-128)", Print(static_cast<signed char>(-128))); // int8 | |
1e59de90 TL |
389 | EXPECT_EQ("65535", Print(std::numeric_limits<uint16_t>::max())); // uint16 |
390 | EXPECT_EQ("-32768", Print(std::numeric_limits<int16_t>::min())); // int16 | |
391 | EXPECT_EQ("4294967295", | |
392 | Print(std::numeric_limits<uint32_t>::max())); // uint32 | |
393 | EXPECT_EQ("-2147483648", | |
394 | Print(std::numeric_limits<int32_t>::min())); // int32 | |
31f18b77 | 395 | EXPECT_EQ("18446744073709551615", |
1e59de90 | 396 | Print(std::numeric_limits<uint64_t>::max())); // uint64 |
31f18b77 | 397 | EXPECT_EQ("-9223372036854775808", |
1e59de90 TL |
398 | Print(std::numeric_limits<int64_t>::min())); // int64 |
399 | #ifdef __cpp_char8_t | |
400 | EXPECT_EQ("U+0000", | |
401 | Print(std::numeric_limits<char8_t>::min())); // char8_t | |
402 | EXPECT_EQ("U+00FF", | |
403 | Print(std::numeric_limits<char8_t>::max())); // char8_t | |
404 | #endif | |
405 | EXPECT_EQ("U+0000", | |
406 | Print(std::numeric_limits<char16_t>::min())); // char16_t | |
407 | EXPECT_EQ("U+FFFF", | |
408 | Print(std::numeric_limits<char16_t>::max())); // char16_t | |
409 | EXPECT_EQ("U+0000", | |
410 | Print(std::numeric_limits<char32_t>::min())); // char32_t | |
411 | EXPECT_EQ("U+FFFFFFFF", | |
412 | Print(std::numeric_limits<char32_t>::max())); // char32_t | |
31f18b77 FG |
413 | } |
414 | ||
415 | // Size types. | |
416 | TEST(PrintBuiltInTypeTest, Size_t) { | |
417 | EXPECT_EQ("1", Print(sizeof('a'))); // size_t. | |
418 | #if !GTEST_OS_WINDOWS | |
419 | // Windows has no ssize_t type. | |
420 | EXPECT_EQ("-2", Print(static_cast<ssize_t>(-2))); // ssize_t. | |
421 | #endif // !GTEST_OS_WINDOWS | |
422 | } | |
423 | ||
424 | // Floating-points. | |
425 | TEST(PrintBuiltInTypeTest, FloatingPoints) { | |
426 | EXPECT_EQ("1.5", Print(1.5f)); // float | |
427 | EXPECT_EQ("-2.5", Print(-2.5)); // double | |
428 | } | |
429 | ||
430 | // Since ::std::stringstream::operator<<(const void *) formats the pointer | |
431 | // output differently with different compilers, we have to create the expected | |
432 | // output first and use it as our expectation. | |
1e59de90 | 433 | static std::string PrintPointer(const void* p) { |
31f18b77 FG |
434 | ::std::stringstream expected_result_stream; |
435 | expected_result_stream << p; | |
436 | return expected_result_stream.str(); | |
437 | } | |
438 | ||
439 | // Tests printing C strings. | |
440 | ||
441 | // const char*. | |
442 | TEST(PrintCStringTest, Const) { | |
443 | const char* p = "World"; | |
444 | EXPECT_EQ(PrintPointer(p) + " pointing to \"World\"", Print(p)); | |
445 | } | |
446 | ||
447 | // char*. | |
448 | TEST(PrintCStringTest, NonConst) { | |
449 | char p[] = "Hi"; | |
450 | EXPECT_EQ(PrintPointer(p) + " pointing to \"Hi\"", | |
451 | Print(static_cast<char*>(p))); | |
452 | } | |
453 | ||
454 | // NULL C string. | |
455 | TEST(PrintCStringTest, Null) { | |
1e59de90 | 456 | const char* p = nullptr; |
31f18b77 FG |
457 | EXPECT_EQ("NULL", Print(p)); |
458 | } | |
459 | ||
460 | // Tests that C strings are escaped properly. | |
461 | TEST(PrintCStringTest, EscapesProperly) { | |
462 | const char* p = "'\"?\\\a\b\f\n\r\t\v\x7F\xFF a"; | |
463 | EXPECT_EQ(PrintPointer(p) + " pointing to \"'\\\"?\\\\\\a\\b\\f" | |
464 | "\\n\\r\\t\\v\\x7F\\xFF a\"", | |
465 | Print(p)); | |
466 | } | |
467 | ||
468 | // MSVC compiler can be configured to define whar_t as a typedef | |
469 | // of unsigned short. Defining an overload for const wchar_t* in that case | |
470 | // would cause pointers to unsigned shorts be printed as wide strings, | |
471 | // possibly accessing more memory than intended and causing invalid | |
472 | // memory accesses. MSVC defines _NATIVE_WCHAR_T_DEFINED symbol when | |
473 | // wchar_t is implemented as a native type. | |
474 | #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) | |
475 | ||
476 | // const wchar_t*. | |
477 | TEST(PrintWideCStringTest, Const) { | |
478 | const wchar_t* p = L"World"; | |
479 | EXPECT_EQ(PrintPointer(p) + " pointing to L\"World\"", Print(p)); | |
480 | } | |
481 | ||
482 | // wchar_t*. | |
483 | TEST(PrintWideCStringTest, NonConst) { | |
484 | wchar_t p[] = L"Hi"; | |
485 | EXPECT_EQ(PrintPointer(p) + " pointing to L\"Hi\"", | |
486 | Print(static_cast<wchar_t*>(p))); | |
487 | } | |
488 | ||
489 | // NULL wide C string. | |
490 | TEST(PrintWideCStringTest, Null) { | |
1e59de90 | 491 | const wchar_t* p = nullptr; |
31f18b77 FG |
492 | EXPECT_EQ("NULL", Print(p)); |
493 | } | |
494 | ||
495 | // Tests that wide C strings are escaped properly. | |
496 | TEST(PrintWideCStringTest, EscapesProperly) { | |
497 | const wchar_t s[] = {'\'', '"', '?', '\\', '\a', '\b', '\f', '\n', '\r', | |
498 | '\t', '\v', 0xD3, 0x576, 0x8D3, 0xC74D, ' ', 'a', '\0'}; | |
499 | EXPECT_EQ(PrintPointer(s) + " pointing to L\"'\\\"?\\\\\\a\\b\\f" | |
500 | "\\n\\r\\t\\v\\xD3\\x576\\x8D3\\xC74D a\"", | |
501 | Print(static_cast<const wchar_t*>(s))); | |
502 | } | |
503 | #endif // native wchar_t | |
504 | ||
505 | // Tests printing pointers to other char types. | |
506 | ||
507 | // signed char*. | |
508 | TEST(PrintCharPointerTest, SignedChar) { | |
509 | signed char* p = reinterpret_cast<signed char*>(0x1234); | |
510 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 511 | p = nullptr; |
31f18b77 FG |
512 | EXPECT_EQ("NULL", Print(p)); |
513 | } | |
514 | ||
515 | // const signed char*. | |
516 | TEST(PrintCharPointerTest, ConstSignedChar) { | |
517 | signed char* p = reinterpret_cast<signed char*>(0x1234); | |
518 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 519 | p = nullptr; |
31f18b77 FG |
520 | EXPECT_EQ("NULL", Print(p)); |
521 | } | |
522 | ||
523 | // unsigned char*. | |
524 | TEST(PrintCharPointerTest, UnsignedChar) { | |
525 | unsigned char* p = reinterpret_cast<unsigned char*>(0x1234); | |
526 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 527 | p = nullptr; |
31f18b77 FG |
528 | EXPECT_EQ("NULL", Print(p)); |
529 | } | |
530 | ||
531 | // const unsigned char*. | |
532 | TEST(PrintCharPointerTest, ConstUnsignedChar) { | |
533 | const unsigned char* p = reinterpret_cast<const unsigned char*>(0x1234); | |
534 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 TL |
535 | p = nullptr; |
536 | EXPECT_EQ("NULL", Print(p)); | |
537 | } | |
538 | ||
539 | #ifdef __cpp_char8_t | |
540 | // char8_t* | |
541 | TEST(PrintCharPointerTest, Char8) { | |
542 | char8_t* p = reinterpret_cast<char8_t*>(0x1234); | |
543 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
544 | p = nullptr; | |
545 | EXPECT_EQ("NULL", Print(p)); | |
546 | } | |
547 | ||
548 | // const char8_t* | |
549 | TEST(PrintCharPointerTest, ConstChar8) { | |
550 | const char8_t* p = reinterpret_cast<const char8_t*>(0x1234); | |
551 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
552 | p = nullptr; | |
553 | EXPECT_EQ("NULL", Print(p)); | |
554 | } | |
555 | #endif | |
556 | ||
557 | // char16_t* | |
558 | TEST(PrintCharPointerTest, Char16) { | |
559 | char16_t* p = reinterpret_cast<char16_t*>(0x1234); | |
560 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
561 | p = nullptr; | |
562 | EXPECT_EQ("NULL", Print(p)); | |
563 | } | |
564 | ||
565 | // const char16_t* | |
566 | TEST(PrintCharPointerTest, ConstChar16) { | |
567 | const char16_t* p = reinterpret_cast<const char16_t*>(0x1234); | |
568 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
569 | p = nullptr; | |
570 | EXPECT_EQ("NULL", Print(p)); | |
571 | } | |
572 | ||
573 | // char32_t* | |
574 | TEST(PrintCharPointerTest, Char32) { | |
575 | char32_t* p = reinterpret_cast<char32_t*>(0x1234); | |
576 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
577 | p = nullptr; | |
578 | EXPECT_EQ("NULL", Print(p)); | |
579 | } | |
580 | ||
581 | // const char32_t* | |
582 | TEST(PrintCharPointerTest, ConstChar32) { | |
583 | const char32_t* p = reinterpret_cast<const char32_t*>(0x1234); | |
584 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
585 | p = nullptr; | |
31f18b77 FG |
586 | EXPECT_EQ("NULL", Print(p)); |
587 | } | |
588 | ||
589 | // Tests printing pointers to simple, built-in types. | |
590 | ||
591 | // bool*. | |
592 | TEST(PrintPointerToBuiltInTypeTest, Bool) { | |
593 | bool* p = reinterpret_cast<bool*>(0xABCD); | |
594 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 595 | p = nullptr; |
31f18b77 FG |
596 | EXPECT_EQ("NULL", Print(p)); |
597 | } | |
598 | ||
599 | // void*. | |
600 | TEST(PrintPointerToBuiltInTypeTest, Void) { | |
601 | void* p = reinterpret_cast<void*>(0xABCD); | |
602 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 603 | p = nullptr; |
31f18b77 FG |
604 | EXPECT_EQ("NULL", Print(p)); |
605 | } | |
606 | ||
607 | // const void*. | |
608 | TEST(PrintPointerToBuiltInTypeTest, ConstVoid) { | |
609 | const void* p = reinterpret_cast<const void*>(0xABCD); | |
610 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 611 | p = nullptr; |
31f18b77 FG |
612 | EXPECT_EQ("NULL", Print(p)); |
613 | } | |
614 | ||
615 | // Tests printing pointers to pointers. | |
616 | TEST(PrintPointerToPointerTest, IntPointerPointer) { | |
617 | int** p = reinterpret_cast<int**>(0xABCD); | |
618 | EXPECT_EQ(PrintPointer(p), Print(p)); | |
1e59de90 | 619 | p = nullptr; |
31f18b77 FG |
620 | EXPECT_EQ("NULL", Print(p)); |
621 | } | |
622 | ||
623 | // Tests printing (non-member) function pointers. | |
624 | ||
625 | void MyFunction(int /* n */) {} | |
626 | ||
627 | TEST(PrintPointerTest, NonMemberFunctionPointer) { | |
628 | // We cannot directly cast &MyFunction to const void* because the | |
629 | // standard disallows casting between pointers to functions and | |
630 | // pointers to objects, and some compilers (e.g. GCC 3.4) enforce | |
631 | // this limitation. | |
632 | EXPECT_EQ( | |
633 | PrintPointer(reinterpret_cast<const void*>( | |
634 | reinterpret_cast<internal::BiggestInt>(&MyFunction))), | |
635 | Print(&MyFunction)); | |
636 | int (*p)(bool) = NULL; // NOLINT | |
637 | EXPECT_EQ("NULL", Print(p)); | |
638 | } | |
639 | ||
640 | // An assertion predicate determining whether a one string is a prefix for | |
641 | // another. | |
642 | template <typename StringType> | |
643 | AssertionResult HasPrefix(const StringType& str, const StringType& prefix) { | |
644 | if (str.find(prefix, 0) == 0) | |
645 | return AssertionSuccess(); | |
646 | ||
647 | const bool is_wide_string = sizeof(prefix[0]) > 1; | |
648 | const char* const begin_string_quote = is_wide_string ? "L\"" : "\""; | |
649 | return AssertionFailure() | |
650 | << begin_string_quote << prefix << "\" is not a prefix of " | |
651 | << begin_string_quote << str << "\"\n"; | |
652 | } | |
653 | ||
654 | // Tests printing member variable pointers. Although they are called | |
655 | // pointers, they don't point to a location in the address space. | |
656 | // Their representation is implementation-defined. Thus they will be | |
657 | // printed as raw bytes. | |
658 | ||
659 | struct Foo { | |
660 | public: | |
661 | virtual ~Foo() {} | |
662 | int MyMethod(char x) { return x + 1; } | |
663 | virtual char MyVirtualMethod(int /* n */) { return 'a'; } | |
664 | ||
665 | int value; | |
666 | }; | |
667 | ||
668 | TEST(PrintPointerTest, MemberVariablePointer) { | |
669 | EXPECT_TRUE(HasPrefix(Print(&Foo::value), | |
670 | Print(sizeof(&Foo::value)) + "-byte object ")); | |
1e59de90 | 671 | int Foo::*p = NULL; // NOLINT |
31f18b77 FG |
672 | EXPECT_TRUE(HasPrefix(Print(p), |
673 | Print(sizeof(p)) + "-byte object ")); | |
674 | } | |
675 | ||
676 | // Tests printing member function pointers. Although they are called | |
677 | // pointers, they don't point to a location in the address space. | |
678 | // Their representation is implementation-defined. Thus they will be | |
679 | // printed as raw bytes. | |
680 | TEST(PrintPointerTest, MemberFunctionPointer) { | |
681 | EXPECT_TRUE(HasPrefix(Print(&Foo::MyMethod), | |
682 | Print(sizeof(&Foo::MyMethod)) + "-byte object ")); | |
683 | EXPECT_TRUE( | |
684 | HasPrefix(Print(&Foo::MyVirtualMethod), | |
685 | Print(sizeof((&Foo::MyVirtualMethod))) + "-byte object ")); | |
686 | int (Foo::*p)(char) = NULL; // NOLINT | |
687 | EXPECT_TRUE(HasPrefix(Print(p), | |
688 | Print(sizeof(p)) + "-byte object ")); | |
689 | } | |
690 | ||
691 | // Tests printing C arrays. | |
692 | ||
693 | // The difference between this and Print() is that it ensures that the | |
694 | // argument is a reference to an array. | |
695 | template <typename T, size_t N> | |
1e59de90 | 696 | std::string PrintArrayHelper(T (&a)[N]) { |
31f18b77 FG |
697 | return Print(a); |
698 | } | |
699 | ||
700 | // One-dimensional array. | |
701 | TEST(PrintArrayTest, OneDimensionalArray) { | |
702 | int a[5] = { 1, 2, 3, 4, 5 }; | |
703 | EXPECT_EQ("{ 1, 2, 3, 4, 5 }", PrintArrayHelper(a)); | |
704 | } | |
705 | ||
706 | // Two-dimensional array. | |
707 | TEST(PrintArrayTest, TwoDimensionalArray) { | |
708 | int a[2][5] = { | |
709 | { 1, 2, 3, 4, 5 }, | |
710 | { 6, 7, 8, 9, 0 } | |
711 | }; | |
712 | EXPECT_EQ("{ { 1, 2, 3, 4, 5 }, { 6, 7, 8, 9, 0 } }", PrintArrayHelper(a)); | |
713 | } | |
714 | ||
715 | // Array of const elements. | |
716 | TEST(PrintArrayTest, ConstArray) { | |
717 | const bool a[1] = { false }; | |
718 | EXPECT_EQ("{ false }", PrintArrayHelper(a)); | |
719 | } | |
720 | ||
721 | // char array without terminating NUL. | |
722 | TEST(PrintArrayTest, CharArrayWithNoTerminatingNul) { | |
723 | // Array a contains '\0' in the middle and doesn't end with '\0'. | |
724 | char a[] = { 'H', '\0', 'i' }; | |
725 | EXPECT_EQ("\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | |
726 | } | |
727 | ||
728 | // const char array with terminating NUL. | |
729 | TEST(PrintArrayTest, ConstCharArrayWithTerminatingNul) { | |
730 | const char a[] = "\0Hi"; | |
731 | EXPECT_EQ("\"\\0Hi\"", PrintArrayHelper(a)); | |
732 | } | |
733 | ||
734 | // const wchar_t array without terminating NUL. | |
735 | TEST(PrintArrayTest, WCharArrayWithNoTerminatingNul) { | |
736 | // Array a contains '\0' in the middle and doesn't end with '\0'. | |
737 | const wchar_t a[] = { L'H', L'\0', L'i' }; | |
738 | EXPECT_EQ("L\"H\\0i\" (no terminating NUL)", PrintArrayHelper(a)); | |
739 | } | |
740 | ||
741 | // wchar_t array with terminating NUL. | |
742 | TEST(PrintArrayTest, WConstCharArrayWithTerminatingNul) { | |
743 | const wchar_t a[] = L"\0Hi"; | |
744 | EXPECT_EQ("L\"\\0Hi\"", PrintArrayHelper(a)); | |
745 | } | |
746 | ||
1e59de90 TL |
747 | #ifdef __cpp_char8_t |
748 | // char8_t array. | |
749 | TEST(PrintArrayTest, Char8Array) { | |
750 | const char8_t a[] = u8"Hello, world!"; | |
751 | EXPECT_EQ( | |
752 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " | |
753 | "U+006F, U+0072, U+006C, U+0064, U+0021, U+0000 }", | |
754 | PrintArrayHelper(a)); | |
755 | } | |
756 | #endif | |
757 | ||
758 | // char16_t array. | |
759 | TEST(PrintArrayTest, Char16Array) { | |
760 | const char16_t a[] = u"Hello, 世界"; | |
761 | EXPECT_EQ( | |
762 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " | |
763 | "U+754C, U+0000 }", | |
764 | PrintArrayHelper(a)); | |
765 | } | |
766 | ||
767 | // char32_t array. | |
768 | TEST(PrintArrayTest, Char32Array) { | |
769 | const char32_t a[] = U"Hello, 世界"; | |
770 | EXPECT_EQ( | |
771 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " | |
772 | "U+754C, U+0000 }", | |
773 | PrintArrayHelper(a)); | |
774 | } | |
775 | ||
31f18b77 FG |
776 | // Array of objects. |
777 | TEST(PrintArrayTest, ObjectArray) { | |
1e59de90 | 778 | std::string a[3] = {"Hi", "Hello", "Ni hao"}; |
31f18b77 FG |
779 | EXPECT_EQ("{ \"Hi\", \"Hello\", \"Ni hao\" }", PrintArrayHelper(a)); |
780 | } | |
781 | ||
782 | // Array with many elements. | |
783 | TEST(PrintArrayTest, BigArray) { | |
784 | int a[100] = { 1, 2, 3 }; | |
785 | EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, ..., 0, 0, 0, 0, 0, 0, 0, 0 }", | |
786 | PrintArrayHelper(a)); | |
787 | } | |
788 | ||
789 | // Tests printing ::string and ::std::string. | |
790 | ||
31f18b77 FG |
791 | // ::std::string. |
792 | TEST(PrintStringTest, StringInStdNamespace) { | |
793 | const char s[] = "'\"?\\\a\b\f\n\0\r\t\v\x7F\xFF a"; | |
794 | const ::std::string str(s, sizeof(s)); | |
795 | EXPECT_EQ("\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v\\x7F\\xFF a\\0\"", | |
796 | Print(str)); | |
797 | } | |
798 | ||
799 | TEST(PrintStringTest, StringAmbiguousHex) { | |
800 | // "\x6BANANA" is ambiguous, it can be interpreted as starting with either of: | |
801 | // '\x6', '\x6B', or '\x6BA'. | |
802 | ||
803 | // a hex escaping sequence following by a decimal digit | |
804 | EXPECT_EQ("\"0\\x12\" \"3\"", Print(::std::string("0\x12" "3"))); | |
805 | // a hex escaping sequence following by a hex digit (lower-case) | |
806 | EXPECT_EQ("\"mm\\x6\" \"bananas\"", Print(::std::string("mm\x6" "bananas"))); | |
807 | // a hex escaping sequence following by a hex digit (upper-case) | |
808 | EXPECT_EQ("\"NOM\\x6\" \"BANANA\"", Print(::std::string("NOM\x6" "BANANA"))); | |
809 | // a hex escaping sequence following by a non-xdigit | |
810 | EXPECT_EQ("\"!\\x5-!\"", Print(::std::string("!\x5-!"))); | |
811 | } | |
812 | ||
1e59de90 | 813 | // Tests printing ::std::wstring. |
31f18b77 FG |
814 | #if GTEST_HAS_STD_WSTRING |
815 | // ::std::wstring. | |
816 | TEST(PrintWideStringTest, StringInStdNamespace) { | |
817 | const wchar_t s[] = L"'\"?\\\a\b\f\n\0\r\t\v\xD3\x576\x8D3\xC74D a"; | |
818 | const ::std::wstring str(s, sizeof(s)/sizeof(wchar_t)); | |
819 | EXPECT_EQ("L\"'\\\"?\\\\\\a\\b\\f\\n\\0\\r\\t\\v" | |
820 | "\\xD3\\x576\\x8D3\\xC74D a\\0\"", | |
821 | Print(str)); | |
822 | } | |
823 | ||
824 | TEST(PrintWideStringTest, StringAmbiguousHex) { | |
825 | // same for wide strings. | |
826 | EXPECT_EQ("L\"0\\x12\" L\"3\"", Print(::std::wstring(L"0\x12" L"3"))); | |
827 | EXPECT_EQ("L\"mm\\x6\" L\"bananas\"", | |
828 | Print(::std::wstring(L"mm\x6" L"bananas"))); | |
829 | EXPECT_EQ("L\"NOM\\x6\" L\"BANANA\"", | |
830 | Print(::std::wstring(L"NOM\x6" L"BANANA"))); | |
831 | EXPECT_EQ("L\"!\\x5-!\"", Print(::std::wstring(L"!\x5-!"))); | |
832 | } | |
833 | #endif // GTEST_HAS_STD_WSTRING | |
834 | ||
1e59de90 TL |
835 | #ifdef __cpp_char8_t |
836 | TEST(PrintStringTest, U8String) { | |
837 | std::u8string str = u8"Hello, world!"; | |
838 | EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. | |
839 | EXPECT_EQ( | |
840 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+0077, " | |
841 | "U+006F, U+0072, U+006C, U+0064, U+0021 }", | |
842 | Print(str)); | |
843 | } | |
844 | #endif | |
845 | ||
846 | TEST(PrintStringTest, U16String) { | |
847 | std::u16string str = u"Hello, 世界"; | |
848 | EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. | |
849 | EXPECT_EQ( | |
850 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " | |
851 | "U+754C }", | |
852 | Print(str)); | |
853 | } | |
854 | ||
855 | TEST(PrintStringTest, U32String) { | |
856 | std::u32string str = U"Hello, 世界"; | |
857 | EXPECT_EQ(str, str); // Verify EXPECT_EQ compiles with this type. | |
858 | EXPECT_EQ( | |
859 | "{ U+0048, U+0065, U+006C, U+006C, U+006F, U+002C, U+0020, U+4E16, " | |
860 | "U+754C }", | |
861 | Print(str)); | |
862 | } | |
863 | ||
31f18b77 FG |
864 | // Tests printing types that support generic streaming (i.e. streaming |
865 | // to std::basic_ostream<Char, CharTraits> for any valid Char and | |
866 | // CharTraits types). | |
867 | ||
868 | // Tests printing a non-template type that supports generic streaming. | |
869 | ||
870 | class AllowsGenericStreaming {}; | |
871 | ||
872 | template <typename Char, typename CharTraits> | |
873 | std::basic_ostream<Char, CharTraits>& operator<<( | |
874 | std::basic_ostream<Char, CharTraits>& os, | |
875 | const AllowsGenericStreaming& /* a */) { | |
876 | return os << "AllowsGenericStreaming"; | |
877 | } | |
878 | ||
879 | TEST(PrintTypeWithGenericStreamingTest, NonTemplateType) { | |
880 | AllowsGenericStreaming a; | |
881 | EXPECT_EQ("AllowsGenericStreaming", Print(a)); | |
882 | } | |
883 | ||
884 | // Tests printing a template type that supports generic streaming. | |
885 | ||
886 | template <typename T> | |
887 | class AllowsGenericStreamingTemplate {}; | |
888 | ||
889 | template <typename Char, typename CharTraits, typename T> | |
890 | std::basic_ostream<Char, CharTraits>& operator<<( | |
891 | std::basic_ostream<Char, CharTraits>& os, | |
892 | const AllowsGenericStreamingTemplate<T>& /* a */) { | |
893 | return os << "AllowsGenericStreamingTemplate"; | |
894 | } | |
895 | ||
896 | TEST(PrintTypeWithGenericStreamingTest, TemplateType) { | |
897 | AllowsGenericStreamingTemplate<int> a; | |
898 | EXPECT_EQ("AllowsGenericStreamingTemplate", Print(a)); | |
899 | } | |
900 | ||
901 | // Tests printing a type that supports generic streaming and can be | |
902 | // implicitly converted to another printable type. | |
903 | ||
904 | template <typename T> | |
905 | class AllowsGenericStreamingAndImplicitConversionTemplate { | |
906 | public: | |
907 | operator bool() const { return false; } | |
908 | }; | |
909 | ||
910 | template <typename Char, typename CharTraits, typename T> | |
911 | std::basic_ostream<Char, CharTraits>& operator<<( | |
912 | std::basic_ostream<Char, CharTraits>& os, | |
913 | const AllowsGenericStreamingAndImplicitConversionTemplate<T>& /* a */) { | |
914 | return os << "AllowsGenericStreamingAndImplicitConversionTemplate"; | |
915 | } | |
916 | ||
917 | TEST(PrintTypeWithGenericStreamingTest, TypeImplicitlyConvertible) { | |
918 | AllowsGenericStreamingAndImplicitConversionTemplate<int> a; | |
919 | EXPECT_EQ("AllowsGenericStreamingAndImplicitConversionTemplate", Print(a)); | |
920 | } | |
921 | ||
1e59de90 | 922 | #if GTEST_INTERNAL_HAS_STRING_VIEW |
31f18b77 | 923 | |
1e59de90 | 924 | // Tests printing internal::StringView. |
31f18b77 | 925 | |
1e59de90 TL |
926 | TEST(PrintStringViewTest, SimpleStringView) { |
927 | const internal::StringView sp = "Hello"; | |
31f18b77 FG |
928 | EXPECT_EQ("\"Hello\"", Print(sp)); |
929 | } | |
930 | ||
1e59de90 | 931 | TEST(PrintStringViewTest, UnprintableCharacters) { |
31f18b77 | 932 | const char str[] = "NUL (\0) and \r\t"; |
1e59de90 | 933 | const internal::StringView sp(str, sizeof(str) - 1); |
31f18b77 FG |
934 | EXPECT_EQ("\"NUL (\\0) and \\r\\t\"", Print(sp)); |
935 | } | |
936 | ||
1e59de90 | 937 | #endif // GTEST_INTERNAL_HAS_STRING_VIEW |
31f18b77 FG |
938 | |
939 | // Tests printing STL containers. | |
940 | ||
941 | TEST(PrintStlContainerTest, EmptyDeque) { | |
942 | deque<char> empty; | |
943 | EXPECT_EQ("{}", Print(empty)); | |
944 | } | |
945 | ||
946 | TEST(PrintStlContainerTest, NonEmptyDeque) { | |
947 | deque<int> non_empty; | |
948 | non_empty.push_back(1); | |
949 | non_empty.push_back(3); | |
950 | EXPECT_EQ("{ 1, 3 }", Print(non_empty)); | |
951 | } | |
952 | ||
31f18b77 FG |
953 | |
954 | TEST(PrintStlContainerTest, OneElementHashMap) { | |
1e59de90 | 955 | ::std::unordered_map<int, char> map1; |
31f18b77 FG |
956 | map1[1] = 'a'; |
957 | EXPECT_EQ("{ (1, 'a' (97, 0x61)) }", Print(map1)); | |
958 | } | |
959 | ||
960 | TEST(PrintStlContainerTest, HashMultiMap) { | |
1e59de90 | 961 | ::std::unordered_multimap<int, bool> map1; |
31f18b77 FG |
962 | map1.insert(make_pair(5, true)); |
963 | map1.insert(make_pair(5, false)); | |
964 | ||
965 | // Elements of hash_multimap can be printed in any order. | |
1e59de90 | 966 | const std::string result = Print(map1); |
31f18b77 FG |
967 | EXPECT_TRUE(result == "{ (5, true), (5, false) }" || |
968 | result == "{ (5, false), (5, true) }") | |
969 | << " where Print(map1) returns \"" << result << "\"."; | |
970 | } | |
971 | ||
31f18b77 | 972 | |
31f18b77 FG |
973 | |
974 | TEST(PrintStlContainerTest, HashSet) { | |
1e59de90 TL |
975 | ::std::unordered_set<int> set1; |
976 | set1.insert(1); | |
977 | EXPECT_EQ("{ 1 }", Print(set1)); | |
31f18b77 FG |
978 | } |
979 | ||
980 | TEST(PrintStlContainerTest, HashMultiSet) { | |
981 | const int kSize = 5; | |
982 | int a[kSize] = { 1, 1, 2, 5, 1 }; | |
1e59de90 | 983 | ::std::unordered_multiset<int> set1(a, a + kSize); |
31f18b77 FG |
984 | |
985 | // Elements of hash_multiset can be printed in any order. | |
1e59de90 TL |
986 | const std::string result = Print(set1); |
987 | const std::string expected_pattern = "{ d, d, d, d, d }"; // d means a digit. | |
31f18b77 FG |
988 | |
989 | // Verifies the result matches the expected pattern; also extracts | |
990 | // the numbers in the result. | |
991 | ASSERT_EQ(expected_pattern.length(), result.length()); | |
992 | std::vector<int> numbers; | |
993 | for (size_t i = 0; i != result.length(); i++) { | |
994 | if (expected_pattern[i] == 'd') { | |
995 | ASSERT_NE(isdigit(static_cast<unsigned char>(result[i])), 0); | |
996 | numbers.push_back(result[i] - '0'); | |
997 | } else { | |
998 | EXPECT_EQ(expected_pattern[i], result[i]) << " where result is " | |
999 | << result; | |
1000 | } | |
1001 | } | |
1002 | ||
1003 | // Makes sure the result contains the right numbers. | |
1004 | std::sort(numbers.begin(), numbers.end()); | |
1005 | std::sort(a, a + kSize); | |
1006 | EXPECT_TRUE(std::equal(a, a + kSize, numbers.begin())); | |
1007 | } | |
1008 | ||
31f18b77 FG |
1009 | |
1010 | TEST(PrintStlContainerTest, List) { | |
1e59de90 TL |
1011 | const std::string a[] = {"hello", "world"}; |
1012 | const list<std::string> strings(a, a + 2); | |
31f18b77 FG |
1013 | EXPECT_EQ("{ \"hello\", \"world\" }", Print(strings)); |
1014 | } | |
1015 | ||
1016 | TEST(PrintStlContainerTest, Map) { | |
1017 | map<int, bool> map1; | |
1018 | map1[1] = true; | |
1019 | map1[5] = false; | |
1020 | map1[3] = true; | |
1021 | EXPECT_EQ("{ (1, true), (3, true), (5, false) }", Print(map1)); | |
1022 | } | |
1023 | ||
1024 | TEST(PrintStlContainerTest, MultiMap) { | |
1025 | multimap<bool, int> map1; | |
1026 | // The make_pair template function would deduce the type as | |
1027 | // pair<bool, int> here, and since the key part in a multimap has to | |
1028 | // be constant, without a templated ctor in the pair class (as in | |
1029 | // libCstd on Solaris), make_pair call would fail to compile as no | |
1030 | // implicit conversion is found. Thus explicit typename is used | |
1031 | // here instead. | |
1032 | map1.insert(pair<const bool, int>(true, 0)); | |
1033 | map1.insert(pair<const bool, int>(true, 1)); | |
1034 | map1.insert(pair<const bool, int>(false, 2)); | |
1035 | EXPECT_EQ("{ (false, 2), (true, 0), (true, 1) }", Print(map1)); | |
1036 | } | |
1037 | ||
1038 | TEST(PrintStlContainerTest, Set) { | |
1039 | const unsigned int a[] = { 3, 0, 5 }; | |
1040 | set<unsigned int> set1(a, a + 3); | |
1041 | EXPECT_EQ("{ 0, 3, 5 }", Print(set1)); | |
1042 | } | |
1043 | ||
1044 | TEST(PrintStlContainerTest, MultiSet) { | |
1045 | const int a[] = { 1, 1, 2, 5, 1 }; | |
1046 | multiset<int> set1(a, a + 5); | |
1047 | EXPECT_EQ("{ 1, 1, 1, 2, 5 }", Print(set1)); | |
1048 | } | |
1049 | ||
31f18b77 FG |
1050 | |
1051 | TEST(PrintStlContainerTest, SinglyLinkedList) { | |
1052 | int a[] = { 9, 2, 8 }; | |
1053 | const std::forward_list<int> ints(a, a + 3); | |
1054 | EXPECT_EQ("{ 9, 2, 8 }", Print(ints)); | |
1055 | } | |
31f18b77 FG |
1056 | |
1057 | TEST(PrintStlContainerTest, Pair) { | |
1058 | pair<const bool, int> p(true, 5); | |
1059 | EXPECT_EQ("(true, 5)", Print(p)); | |
1060 | } | |
1061 | ||
1062 | TEST(PrintStlContainerTest, Vector) { | |
1063 | vector<int> v; | |
1064 | v.push_back(1); | |
1065 | v.push_back(2); | |
1066 | EXPECT_EQ("{ 1, 2 }", Print(v)); | |
1067 | } | |
1068 | ||
1069 | TEST(PrintStlContainerTest, LongSequence) { | |
1070 | const int a[100] = { 1, 2, 3 }; | |
1071 | const vector<int> v(a, a + 100); | |
1072 | EXPECT_EQ("{ 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, " | |
1073 | "0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ... }", Print(v)); | |
1074 | } | |
1075 | ||
1076 | TEST(PrintStlContainerTest, NestedContainer) { | |
1077 | const int a1[] = { 1, 2 }; | |
1078 | const int a2[] = { 3, 4, 5 }; | |
1079 | const list<int> l1(a1, a1 + 2); | |
1080 | const list<int> l2(a2, a2 + 3); | |
1081 | ||
1082 | vector<list<int> > v; | |
1083 | v.push_back(l1); | |
1084 | v.push_back(l2); | |
1085 | EXPECT_EQ("{ { 1, 2 }, { 3, 4, 5 } }", Print(v)); | |
1086 | } | |
1087 | ||
1088 | TEST(PrintStlContainerTest, OneDimensionalNativeArray) { | |
1089 | const int a[3] = { 1, 2, 3 }; | |
1090 | NativeArray<int> b(a, 3, RelationToSourceReference()); | |
1091 | EXPECT_EQ("{ 1, 2, 3 }", Print(b)); | |
1092 | } | |
1093 | ||
1094 | TEST(PrintStlContainerTest, TwoDimensionalNativeArray) { | |
1095 | const int a[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } }; | |
1096 | NativeArray<int[3]> b(a, 2, RelationToSourceReference()); | |
1097 | EXPECT_EQ("{ { 1, 2, 3 }, { 4, 5, 6 } }", Print(b)); | |
1098 | } | |
1099 | ||
1100 | // Tests that a class named iterator isn't treated as a container. | |
1101 | ||
1102 | struct iterator { | |
1103 | char x; | |
1104 | }; | |
1105 | ||
1106 | TEST(PrintStlContainerTest, Iterator) { | |
1107 | iterator it = {}; | |
1108 | EXPECT_EQ("1-byte object <00>", Print(it)); | |
1109 | } | |
1110 | ||
1111 | // Tests that a class named const_iterator isn't treated as a container. | |
1112 | ||
1113 | struct const_iterator { | |
1114 | char x; | |
1115 | }; | |
1116 | ||
1117 | TEST(PrintStlContainerTest, ConstIterator) { | |
1118 | const_iterator it = {}; | |
1119 | EXPECT_EQ("1-byte object <00>", Print(it)); | |
1120 | } | |
1121 | ||
31f18b77 FG |
1122 | // Tests printing ::std::tuples. |
1123 | ||
1124 | // Tuples of various arities. | |
1125 | TEST(PrintStdTupleTest, VariousSizes) { | |
1126 | ::std::tuple<> t0; | |
1127 | EXPECT_EQ("()", Print(t0)); | |
1128 | ||
1129 | ::std::tuple<int> t1(5); | |
1130 | EXPECT_EQ("(5)", Print(t1)); | |
1131 | ||
1132 | ::std::tuple<char, bool> t2('a', true); | |
1133 | EXPECT_EQ("('a' (97, 0x61), true)", Print(t2)); | |
1134 | ||
1135 | ::std::tuple<bool, int, int> t3(false, 2, 3); | |
1136 | EXPECT_EQ("(false, 2, 3)", Print(t3)); | |
1137 | ||
1138 | ::std::tuple<bool, int, int, int> t4(false, 2, 3, 4); | |
1139 | EXPECT_EQ("(false, 2, 3, 4)", Print(t4)); | |
1140 | ||
31f18b77 | 1141 | const char* const str = "8"; |
1e59de90 TL |
1142 | ::std::tuple<bool, char, short, int32_t, int64_t, float, double, // NOLINT |
1143 | const char*, void*, std::string> | |
1144 | t10(false, 'a', static_cast<short>(3), 4, 5, 1.5F, -2.5, str, // NOLINT | |
1145 | nullptr, "10"); | |
31f18b77 FG |
1146 | EXPECT_EQ("(false, 'a' (97, 0x61), 3, 4, 5, 1.5, -2.5, " + PrintPointer(str) + |
1147 | " pointing to \"8\", NULL, \"10\")", | |
1148 | Print(t10)); | |
1149 | } | |
1150 | ||
1151 | // Nested tuples. | |
1152 | TEST(PrintStdTupleTest, NestedTuple) { | |
1153 | ::std::tuple< ::std::tuple<int, bool>, char> nested( | |
1154 | ::std::make_tuple(5, true), 'a'); | |
1155 | EXPECT_EQ("((5, true), 'a' (97, 0x61))", Print(nested)); | |
1156 | } | |
1157 | ||
1e59de90 TL |
1158 | TEST(PrintNullptrT, Basic) { |
1159 | EXPECT_EQ("(nullptr)", Print(nullptr)); | |
1160 | } | |
1161 | ||
1162 | TEST(PrintReferenceWrapper, Printable) { | |
1163 | int x = 5; | |
1164 | EXPECT_EQ("@" + PrintPointer(&x) + " 5", Print(std::ref(x))); | |
1165 | EXPECT_EQ("@" + PrintPointer(&x) + " 5", Print(std::cref(x))); | |
1166 | } | |
1167 | ||
1168 | TEST(PrintReferenceWrapper, Unprintable) { | |
1169 | ::foo::UnprintableInFoo up; | |
1170 | EXPECT_EQ( | |
1171 | "@" + PrintPointer(&up) + | |
1172 | " 16-byte object <EF-12 00-00 34-AB 00-00 00-00 00-00 00-00 00-00>", | |
1173 | Print(std::ref(up))); | |
1174 | EXPECT_EQ( | |
1175 | "@" + PrintPointer(&up) + | |
1176 | " 16-byte object <EF-12 00-00 34-AB 00-00 00-00 00-00 00-00 00-00>", | |
1177 | Print(std::cref(up))); | |
1178 | } | |
31f18b77 FG |
1179 | |
1180 | // Tests printing user-defined unprintable types. | |
1181 | ||
1182 | // Unprintable types in the global namespace. | |
1183 | TEST(PrintUnprintableTypeTest, InGlobalNamespace) { | |
1184 | EXPECT_EQ("1-byte object <00>", | |
1185 | Print(UnprintableTemplateInGlobal<char>())); | |
1186 | } | |
1187 | ||
1188 | // Unprintable types in a user namespace. | |
1189 | TEST(PrintUnprintableTypeTest, InUserNamespace) { | |
1190 | EXPECT_EQ("16-byte object <EF-12 00-00 34-AB 00-00 00-00 00-00 00-00 00-00>", | |
1191 | Print(::foo::UnprintableInFoo())); | |
1192 | } | |
1193 | ||
1194 | // Unprintable types are that too big to be printed completely. | |
1195 | ||
1196 | struct Big { | |
1197 | Big() { memset(array, 0, sizeof(array)); } | |
1198 | char array[257]; | |
1199 | }; | |
1200 | ||
1201 | TEST(PrintUnpritableTypeTest, BigObject) { | |
1202 | EXPECT_EQ("257-byte object <00-00 00-00 00-00 00-00 00-00 00-00 " | |
1203 | "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " | |
1204 | "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " | |
1205 | "00-00 00-00 00-00 00-00 00-00 00-00 ... 00-00 00-00 00-00 " | |
1206 | "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " | |
1207 | "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 " | |
1208 | "00-00 00-00 00-00 00-00 00-00 00-00 00-00 00-00 00>", | |
1209 | Print(Big())); | |
1210 | } | |
1211 | ||
1212 | // Tests printing user-defined streamable types. | |
1213 | ||
1214 | // Streamable types in the global namespace. | |
1215 | TEST(PrintStreamableTypeTest, InGlobalNamespace) { | |
1216 | StreamableInGlobal x; | |
1217 | EXPECT_EQ("StreamableInGlobal", Print(x)); | |
1218 | EXPECT_EQ("StreamableInGlobal*", Print(&x)); | |
1219 | } | |
1220 | ||
1221 | // Printable template types in a user namespace. | |
1222 | TEST(PrintStreamableTypeTest, TemplateTypeInUserNamespace) { | |
1223 | EXPECT_EQ("StreamableTemplateInFoo: 0", | |
1224 | Print(::foo::StreamableTemplateInFoo<int>())); | |
1225 | } | |
1226 | ||
1e59de90 TL |
1227 | TEST(PrintStreamableTypeTest, TypeInUserNamespaceWithTemplatedStreamOperator) { |
1228 | EXPECT_EQ("TemplatedStreamableInFoo", | |
1229 | Print(::foo::TemplatedStreamableInFoo())); | |
1230 | } | |
1231 | ||
1232 | TEST(PrintStreamableTypeTest, SubclassUsesSuperclassStreamOperator) { | |
1233 | ParentClass parent; | |
1234 | ChildClassWithStreamOperator child_stream; | |
1235 | ChildClassWithoutStreamOperator child_no_stream; | |
1236 | EXPECT_EQ("ParentClass", Print(parent)); | |
1237 | EXPECT_EQ("ChildClassWithStreamOperator", Print(child_stream)); | |
1238 | EXPECT_EQ("ParentClass", Print(child_no_stream)); | |
1239 | } | |
1240 | ||
1241 | // Tests printing a user-defined recursive container type that has a << | |
1242 | // operator. | |
1243 | TEST(PrintStreamableTypeTest, PathLikeInUserNamespace) { | |
1244 | ::foo::PathLike x; | |
1245 | EXPECT_EQ("Streamable-PathLike", Print(x)); | |
1246 | const ::foo::PathLike cx; | |
1247 | EXPECT_EQ("Streamable-PathLike", Print(cx)); | |
1248 | } | |
1249 | ||
31f18b77 FG |
1250 | // Tests printing user-defined types that have a PrintTo() function. |
1251 | TEST(PrintPrintableTypeTest, InUserNamespace) { | |
1252 | EXPECT_EQ("PrintableViaPrintTo: 0", | |
1253 | Print(::foo::PrintableViaPrintTo())); | |
1254 | } | |
1255 | ||
1256 | // Tests printing a pointer to a user-defined type that has a << | |
1257 | // operator for its pointer. | |
1258 | TEST(PrintPrintableTypeTest, PointerInUserNamespace) { | |
1259 | ::foo::PointerPrintable x; | |
1260 | EXPECT_EQ("PointerPrintable*", Print(&x)); | |
1261 | } | |
1262 | ||
1263 | // Tests printing user-defined class template that have a PrintTo() function. | |
1264 | TEST(PrintPrintableTypeTest, TemplateInUserNamespace) { | |
1265 | EXPECT_EQ("PrintableViaPrintToTemplate: 5", | |
1266 | Print(::foo::PrintableViaPrintToTemplate<int>(5))); | |
1267 | } | |
1268 | ||
1269 | // Tests that the universal printer prints both the address and the | |
1270 | // value of a reference. | |
1271 | TEST(PrintReferenceTest, PrintsAddressAndValue) { | |
1272 | int n = 5; | |
1273 | EXPECT_EQ("@" + PrintPointer(&n) + " 5", PrintByRef(n)); | |
1274 | ||
1275 | int a[2][3] = { | |
1276 | { 0, 1, 2 }, | |
1277 | { 3, 4, 5 } | |
1278 | }; | |
1279 | EXPECT_EQ("@" + PrintPointer(a) + " { { 0, 1, 2 }, { 3, 4, 5 } }", | |
1280 | PrintByRef(a)); | |
1281 | ||
1282 | const ::foo::UnprintableInFoo x; | |
1283 | EXPECT_EQ("@" + PrintPointer(&x) + " 16-byte object " | |
1284 | "<EF-12 00-00 34-AB 00-00 00-00 00-00 00-00 00-00>", | |
1285 | PrintByRef(x)); | |
1286 | } | |
1287 | ||
1288 | // Tests that the universal printer prints a function pointer passed by | |
1289 | // reference. | |
1290 | TEST(PrintReferenceTest, HandlesFunctionPointer) { | |
1291 | void (*fp)(int n) = &MyFunction; | |
1e59de90 | 1292 | const std::string fp_pointer_string = |
31f18b77 FG |
1293 | PrintPointer(reinterpret_cast<const void*>(&fp)); |
1294 | // We cannot directly cast &MyFunction to const void* because the | |
1295 | // standard disallows casting between pointers to functions and | |
1296 | // pointers to objects, and some compilers (e.g. GCC 3.4) enforce | |
1297 | // this limitation. | |
1e59de90 | 1298 | const std::string fp_string = PrintPointer(reinterpret_cast<const void*>( |
31f18b77 FG |
1299 | reinterpret_cast<internal::BiggestInt>(fp))); |
1300 | EXPECT_EQ("@" + fp_pointer_string + " " + fp_string, | |
1301 | PrintByRef(fp)); | |
1302 | } | |
1303 | ||
1304 | // Tests that the universal printer prints a member function pointer | |
1305 | // passed by reference. | |
1306 | TEST(PrintReferenceTest, HandlesMemberFunctionPointer) { | |
1307 | int (Foo::*p)(char ch) = &Foo::MyMethod; | |
1308 | EXPECT_TRUE(HasPrefix( | |
1309 | PrintByRef(p), | |
1310 | "@" + PrintPointer(reinterpret_cast<const void*>(&p)) + " " + | |
1311 | Print(sizeof(p)) + "-byte object ")); | |
1312 | ||
1313 | char (Foo::*p2)(int n) = &Foo::MyVirtualMethod; | |
1314 | EXPECT_TRUE(HasPrefix( | |
1315 | PrintByRef(p2), | |
1316 | "@" + PrintPointer(reinterpret_cast<const void*>(&p2)) + " " + | |
1317 | Print(sizeof(p2)) + "-byte object ")); | |
1318 | } | |
1319 | ||
1320 | // Tests that the universal printer prints a member variable pointer | |
1321 | // passed by reference. | |
1322 | TEST(PrintReferenceTest, HandlesMemberVariablePointer) { | |
1e59de90 | 1323 | int Foo::*p = &Foo::value; // NOLINT |
31f18b77 FG |
1324 | EXPECT_TRUE(HasPrefix( |
1325 | PrintByRef(p), | |
1326 | "@" + PrintPointer(&p) + " " + Print(sizeof(p)) + "-byte object ")); | |
1327 | } | |
1328 | ||
1329 | // Tests that FormatForComparisonFailureMessage(), which is used to print | |
1330 | // an operand in a comparison assertion (e.g. ASSERT_EQ) when the assertion | |
1331 | // fails, formats the operand in the desired way. | |
1332 | ||
1333 | // scalar | |
1334 | TEST(FormatForComparisonFailureMessageTest, WorksForScalar) { | |
1335 | EXPECT_STREQ("123", | |
1336 | FormatForComparisonFailureMessage(123, 124).c_str()); | |
1337 | } | |
1338 | ||
1339 | // non-char pointer | |
1340 | TEST(FormatForComparisonFailureMessageTest, WorksForNonCharPointer) { | |
1341 | int n = 0; | |
1342 | EXPECT_EQ(PrintPointer(&n), | |
1343 | FormatForComparisonFailureMessage(&n, &n).c_str()); | |
1344 | } | |
1345 | ||
1346 | // non-char array | |
1347 | TEST(FormatForComparisonFailureMessageTest, FormatsNonCharArrayAsPointer) { | |
1348 | // In expression 'array == x', 'array' is compared by pointer. | |
1349 | // Therefore we want to print an array operand as a pointer. | |
1350 | int n[] = { 1, 2, 3 }; | |
1351 | EXPECT_EQ(PrintPointer(n), | |
1352 | FormatForComparisonFailureMessage(n, n).c_str()); | |
1353 | } | |
1354 | ||
1355 | // Tests formatting a char pointer when it's compared with another pointer. | |
1e59de90 | 1356 | // In this case we want to print it as a raw pointer, as the comparison is by |
31f18b77 FG |
1357 | // pointer. |
1358 | ||
1359 | // char pointer vs pointer | |
1360 | TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsPointer) { | |
1361 | // In expression 'p == x', where 'p' and 'x' are (const or not) char | |
1362 | // pointers, the operands are compared by pointer. Therefore we | |
1363 | // want to print 'p' as a pointer instead of a C string (we don't | |
1364 | // even know if it's supposed to point to a valid C string). | |
1365 | ||
1366 | // const char* | |
1367 | const char* s = "hello"; | |
1368 | EXPECT_EQ(PrintPointer(s), | |
1369 | FormatForComparisonFailureMessage(s, s).c_str()); | |
1370 | ||
1371 | // char* | |
1372 | char ch = 'a'; | |
1373 | EXPECT_EQ(PrintPointer(&ch), | |
1374 | FormatForComparisonFailureMessage(&ch, &ch).c_str()); | |
1375 | } | |
1376 | ||
1377 | // wchar_t pointer vs pointer | |
1378 | TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsPointer) { | |
1379 | // In expression 'p == x', where 'p' and 'x' are (const or not) char | |
1380 | // pointers, the operands are compared by pointer. Therefore we | |
1381 | // want to print 'p' as a pointer instead of a wide C string (we don't | |
1382 | // even know if it's supposed to point to a valid wide C string). | |
1383 | ||
1384 | // const wchar_t* | |
1385 | const wchar_t* s = L"hello"; | |
1386 | EXPECT_EQ(PrintPointer(s), | |
1387 | FormatForComparisonFailureMessage(s, s).c_str()); | |
1388 | ||
1389 | // wchar_t* | |
1390 | wchar_t ch = L'a'; | |
1391 | EXPECT_EQ(PrintPointer(&ch), | |
1392 | FormatForComparisonFailureMessage(&ch, &ch).c_str()); | |
1393 | } | |
1394 | ||
1395 | // Tests formatting a char pointer when it's compared to a string object. | |
1396 | // In this case we want to print the char pointer as a C string. | |
1397 | ||
31f18b77 FG |
1398 | // char pointer vs std::string |
1399 | TEST(FormatForComparisonFailureMessageTest, WorksForCharPointerVsStdString) { | |
1400 | const char* s = "hello \"world"; | |
1401 | EXPECT_STREQ("\"hello \\\"world\"", // The string content should be escaped. | |
1402 | FormatForComparisonFailureMessage(s, ::std::string()).c_str()); | |
1403 | ||
1404 | // char* | |
1405 | char str[] = "hi\1"; | |
1406 | char* p = str; | |
1407 | EXPECT_STREQ("\"hi\\x1\"", // The string content should be escaped. | |
1408 | FormatForComparisonFailureMessage(p, ::std::string()).c_str()); | |
1409 | } | |
1410 | ||
31f18b77 FG |
1411 | #if GTEST_HAS_STD_WSTRING |
1412 | // wchar_t pointer vs std::wstring | |
1413 | TEST(FormatForComparisonFailureMessageTest, WorksForWCharPointerVsStdWString) { | |
1414 | const wchar_t* s = L"hi \"world"; | |
1415 | EXPECT_STREQ("L\"hi \\\"world\"", // The string content should be escaped. | |
1416 | FormatForComparisonFailureMessage(s, ::std::wstring()).c_str()); | |
1417 | ||
1418 | // wchar_t* | |
1419 | wchar_t str[] = L"hi\1"; | |
1420 | wchar_t* p = str; | |
1421 | EXPECT_STREQ("L\"hi\\x1\"", // The string content should be escaped. | |
1422 | FormatForComparisonFailureMessage(p, ::std::wstring()).c_str()); | |
1423 | } | |
1424 | #endif | |
1425 | ||
1426 | // Tests formatting a char array when it's compared with a pointer or array. | |
1427 | // In this case we want to print the array as a row pointer, as the comparison | |
1428 | // is by pointer. | |
1429 | ||
1430 | // char array vs pointer | |
1431 | TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsPointer) { | |
1432 | char str[] = "hi \"world\""; | |
1e59de90 | 1433 | char* p = nullptr; |
31f18b77 FG |
1434 | EXPECT_EQ(PrintPointer(str), |
1435 | FormatForComparisonFailureMessage(str, p).c_str()); | |
1436 | } | |
1437 | ||
1438 | // char array vs char array | |
1439 | TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsCharArray) { | |
1440 | const char str[] = "hi \"world\""; | |
1441 | EXPECT_EQ(PrintPointer(str), | |
1442 | FormatForComparisonFailureMessage(str, str).c_str()); | |
1443 | } | |
1444 | ||
1445 | // wchar_t array vs pointer | |
1446 | TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsPointer) { | |
1447 | wchar_t str[] = L"hi \"world\""; | |
1e59de90 | 1448 | wchar_t* p = nullptr; |
31f18b77 FG |
1449 | EXPECT_EQ(PrintPointer(str), |
1450 | FormatForComparisonFailureMessage(str, p).c_str()); | |
1451 | } | |
1452 | ||
1453 | // wchar_t array vs wchar_t array | |
1454 | TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsWCharArray) { | |
1455 | const wchar_t str[] = L"hi \"world\""; | |
1456 | EXPECT_EQ(PrintPointer(str), | |
1457 | FormatForComparisonFailureMessage(str, str).c_str()); | |
1458 | } | |
1459 | ||
1460 | // Tests formatting a char array when it's compared with a string object. | |
1461 | // In this case we want to print the array as a C string. | |
1462 | ||
31f18b77 FG |
1463 | // char array vs std::string |
1464 | TEST(FormatForComparisonFailureMessageTest, WorksForCharArrayVsStdString) { | |
1465 | const char str[] = "hi \"world\""; | |
1466 | EXPECT_STREQ("\"hi \\\"world\\\"\"", // The content should be escaped. | |
1467 | FormatForComparisonFailureMessage(str, ::std::string()).c_str()); | |
1468 | } | |
1469 | ||
31f18b77 FG |
1470 | #if GTEST_HAS_STD_WSTRING |
1471 | // wchar_t array vs std::wstring | |
1472 | TEST(FormatForComparisonFailureMessageTest, WorksForWCharArrayVsStdWString) { | |
1473 | const wchar_t str[] = L"hi \"w\0rld\""; | |
1474 | EXPECT_STREQ( | |
1475 | "L\"hi \\\"w\"", // The content should be escaped. | |
1476 | // Embedded NUL terminates the string. | |
1477 | FormatForComparisonFailureMessage(str, ::std::wstring()).c_str()); | |
1478 | } | |
1479 | #endif | |
1480 | ||
1481 | // Useful for testing PrintToString(). We cannot use EXPECT_EQ() | |
1482 | // there as its implementation uses PrintToString(). The caller must | |
1483 | // ensure that 'value' has no side effect. | |
1484 | #define EXPECT_PRINT_TO_STRING_(value, expected_string) \ | |
1485 | EXPECT_TRUE(PrintToString(value) == (expected_string)) \ | |
1486 | << " where " #value " prints as " << (PrintToString(value)) | |
1487 | ||
1488 | TEST(PrintToStringTest, WorksForScalar) { | |
1489 | EXPECT_PRINT_TO_STRING_(123, "123"); | |
1490 | } | |
1491 | ||
1492 | TEST(PrintToStringTest, WorksForPointerToConstChar) { | |
1493 | const char* p = "hello"; | |
1494 | EXPECT_PRINT_TO_STRING_(p, "\"hello\""); | |
1495 | } | |
1496 | ||
1497 | TEST(PrintToStringTest, WorksForPointerToNonConstChar) { | |
1498 | char s[] = "hello"; | |
1499 | char* p = s; | |
1500 | EXPECT_PRINT_TO_STRING_(p, "\"hello\""); | |
1501 | } | |
1502 | ||
1503 | TEST(PrintToStringTest, EscapesForPointerToConstChar) { | |
1504 | const char* p = "hello\n"; | |
1505 | EXPECT_PRINT_TO_STRING_(p, "\"hello\\n\""); | |
1506 | } | |
1507 | ||
1508 | TEST(PrintToStringTest, EscapesForPointerToNonConstChar) { | |
1509 | char s[] = "hello\1"; | |
1510 | char* p = s; | |
1511 | EXPECT_PRINT_TO_STRING_(p, "\"hello\\x1\""); | |
1512 | } | |
1513 | ||
1514 | TEST(PrintToStringTest, WorksForArray) { | |
1515 | int n[3] = { 1, 2, 3 }; | |
1516 | EXPECT_PRINT_TO_STRING_(n, "{ 1, 2, 3 }"); | |
1517 | } | |
1518 | ||
1519 | TEST(PrintToStringTest, WorksForCharArray) { | |
1520 | char s[] = "hello"; | |
1521 | EXPECT_PRINT_TO_STRING_(s, "\"hello\""); | |
1522 | } | |
1523 | ||
1524 | TEST(PrintToStringTest, WorksForCharArrayWithEmbeddedNul) { | |
1525 | const char str_with_nul[] = "hello\0 world"; | |
1526 | EXPECT_PRINT_TO_STRING_(str_with_nul, "\"hello\\0 world\""); | |
1527 | ||
1528 | char mutable_str_with_nul[] = "hello\0 world"; | |
1529 | EXPECT_PRINT_TO_STRING_(mutable_str_with_nul, "\"hello\\0 world\""); | |
1530 | } | |
1531 | ||
1e59de90 TL |
1532 | TEST(PrintToStringTest, ContainsNonLatin) { |
1533 | // Sanity test with valid UTF-8. Prints both in hex and as text. | |
1534 | std::string non_ascii_str = ::std::string("오전 4:30"); | |
1535 | EXPECT_PRINT_TO_STRING_(non_ascii_str, | |
1536 | "\"\\xEC\\x98\\xA4\\xEC\\xA0\\x84 4:30\"\n" | |
1537 | " As Text: \"오전 4:30\""); | |
1538 | non_ascii_str = ::std::string("From ä — ẑ"); | |
1539 | EXPECT_PRINT_TO_STRING_(non_ascii_str, | |
1540 | "\"From \\xC3\\xA4 \\xE2\\x80\\x94 \\xE1\\xBA\\x91\"" | |
1541 | "\n As Text: \"From ä — ẑ\""); | |
1542 | } | |
1543 | ||
1544 | TEST(IsValidUTF8Test, IllFormedUTF8) { | |
1545 | // The following test strings are ill-formed UTF-8 and are printed | |
1546 | // as hex only (or ASCII, in case of ASCII bytes) because IsValidUTF8() is | |
1547 | // expected to fail, thus output does not contain "As Text:". | |
1548 | ||
1549 | static const char *const kTestdata[][2] = { | |
1550 | // 2-byte lead byte followed by a single-byte character. | |
1551 | {"\xC3\x74", "\"\\xC3t\""}, | |
1552 | // Valid 2-byte character followed by an orphan trail byte. | |
1553 | {"\xC3\x84\xA4", "\"\\xC3\\x84\\xA4\""}, | |
1554 | // Lead byte without trail byte. | |
1555 | {"abc\xC3", "\"abc\\xC3\""}, | |
1556 | // 3-byte lead byte, single-byte character, orphan trail byte. | |
1557 | {"x\xE2\x70\x94", "\"x\\xE2p\\x94\""}, | |
1558 | // Truncated 3-byte character. | |
1559 | {"\xE2\x80", "\"\\xE2\\x80\""}, | |
1560 | // Truncated 3-byte character followed by valid 2-byte char. | |
1561 | {"\xE2\x80\xC3\x84", "\"\\xE2\\x80\\xC3\\x84\""}, | |
1562 | // Truncated 3-byte character followed by a single-byte character. | |
1563 | {"\xE2\x80\x7A", "\"\\xE2\\x80z\""}, | |
1564 | // 3-byte lead byte followed by valid 3-byte character. | |
1565 | {"\xE2\xE2\x80\x94", "\"\\xE2\\xE2\\x80\\x94\""}, | |
1566 | // 4-byte lead byte followed by valid 3-byte character. | |
1567 | {"\xF0\xE2\x80\x94", "\"\\xF0\\xE2\\x80\\x94\""}, | |
1568 | // Truncated 4-byte character. | |
1569 | {"\xF0\xE2\x80", "\"\\xF0\\xE2\\x80\""}, | |
1570 | // Invalid UTF-8 byte sequences embedded in other chars. | |
1571 | {"abc\xE2\x80\x94\xC3\x74xyc", "\"abc\\xE2\\x80\\x94\\xC3txyc\""}, | |
1572 | {"abc\xC3\x84\xE2\x80\xC3\x84xyz", | |
1573 | "\"abc\\xC3\\x84\\xE2\\x80\\xC3\\x84xyz\""}, | |
1574 | // Non-shortest UTF-8 byte sequences are also ill-formed. | |
1575 | // The classics: xC0, xC1 lead byte. | |
1576 | {"\xC0\x80", "\"\\xC0\\x80\""}, | |
1577 | {"\xC1\x81", "\"\\xC1\\x81\""}, | |
1578 | // Non-shortest sequences. | |
1579 | {"\xE0\x80\x80", "\"\\xE0\\x80\\x80\""}, | |
1580 | {"\xf0\x80\x80\x80", "\"\\xF0\\x80\\x80\\x80\""}, | |
1581 | // Last valid code point before surrogate range, should be printed as text, | |
1582 | // too. | |
1583 | {"\xED\x9F\xBF", "\"\\xED\\x9F\\xBF\"\n As Text: \"\""}, | |
1584 | // Start of surrogate lead. Surrogates are not printed as text. | |
1585 | {"\xED\xA0\x80", "\"\\xED\\xA0\\x80\""}, | |
1586 | // Last non-private surrogate lead. | |
1587 | {"\xED\xAD\xBF", "\"\\xED\\xAD\\xBF\""}, | |
1588 | // First private-use surrogate lead. | |
1589 | {"\xED\xAE\x80", "\"\\xED\\xAE\\x80\""}, | |
1590 | // Last private-use surrogate lead. | |
1591 | {"\xED\xAF\xBF", "\"\\xED\\xAF\\xBF\""}, | |
1592 | // Mid-point of surrogate trail. | |
1593 | {"\xED\xB3\xBF", "\"\\xED\\xB3\\xBF\""}, | |
1594 | // First valid code point after surrogate range, should be printed as text, | |
1595 | // too. | |
1596 | {"\xEE\x80\x80", "\"\\xEE\\x80\\x80\"\n As Text: \"\""} | |
1597 | }; | |
1598 | ||
1599 | for (int i = 0; i < int(sizeof(kTestdata)/sizeof(kTestdata[0])); ++i) { | |
1600 | EXPECT_PRINT_TO_STRING_(kTestdata[i][0], kTestdata[i][1]); | |
1601 | } | |
1602 | } | |
1603 | ||
31f18b77 FG |
1604 | #undef EXPECT_PRINT_TO_STRING_ |
1605 | ||
1606 | TEST(UniversalTersePrintTest, WorksForNonReference) { | |
1607 | ::std::stringstream ss; | |
1608 | UniversalTersePrint(123, &ss); | |
1609 | EXPECT_EQ("123", ss.str()); | |
1610 | } | |
1611 | ||
1612 | TEST(UniversalTersePrintTest, WorksForReference) { | |
1613 | const int& n = 123; | |
1614 | ::std::stringstream ss; | |
1615 | UniversalTersePrint(n, &ss); | |
1616 | EXPECT_EQ("123", ss.str()); | |
1617 | } | |
1618 | ||
1619 | TEST(UniversalTersePrintTest, WorksForCString) { | |
1620 | const char* s1 = "abc"; | |
1621 | ::std::stringstream ss1; | |
1622 | UniversalTersePrint(s1, &ss1); | |
1623 | EXPECT_EQ("\"abc\"", ss1.str()); | |
1624 | ||
1625 | char* s2 = const_cast<char*>(s1); | |
1626 | ::std::stringstream ss2; | |
1627 | UniversalTersePrint(s2, &ss2); | |
1628 | EXPECT_EQ("\"abc\"", ss2.str()); | |
1629 | ||
1e59de90 | 1630 | const char* s3 = nullptr; |
31f18b77 FG |
1631 | ::std::stringstream ss3; |
1632 | UniversalTersePrint(s3, &ss3); | |
1633 | EXPECT_EQ("NULL", ss3.str()); | |
1634 | } | |
1635 | ||
1636 | TEST(UniversalPrintTest, WorksForNonReference) { | |
1637 | ::std::stringstream ss; | |
1638 | UniversalPrint(123, &ss); | |
1639 | EXPECT_EQ("123", ss.str()); | |
1640 | } | |
1641 | ||
1642 | TEST(UniversalPrintTest, WorksForReference) { | |
1643 | const int& n = 123; | |
1644 | ::std::stringstream ss; | |
1645 | UniversalPrint(n, &ss); | |
1646 | EXPECT_EQ("123", ss.str()); | |
1647 | } | |
1648 | ||
1649 | TEST(UniversalPrintTest, WorksForCString) { | |
1650 | const char* s1 = "abc"; | |
1651 | ::std::stringstream ss1; | |
1652 | UniversalPrint(s1, &ss1); | |
1e59de90 | 1653 | EXPECT_EQ(PrintPointer(s1) + " pointing to \"abc\"", std::string(ss1.str())); |
31f18b77 FG |
1654 | |
1655 | char* s2 = const_cast<char*>(s1); | |
1656 | ::std::stringstream ss2; | |
1657 | UniversalPrint(s2, &ss2); | |
1e59de90 | 1658 | EXPECT_EQ(PrintPointer(s2) + " pointing to \"abc\"", std::string(ss2.str())); |
31f18b77 | 1659 | |
1e59de90 | 1660 | const char* s3 = nullptr; |
31f18b77 FG |
1661 | ::std::stringstream ss3; |
1662 | UniversalPrint(s3, &ss3); | |
1663 | EXPECT_EQ("NULL", ss3.str()); | |
1664 | } | |
1665 | ||
1666 | TEST(UniversalPrintTest, WorksForCharArray) { | |
1667 | const char str[] = "\"Line\0 1\"\nLine 2"; | |
1668 | ::std::stringstream ss1; | |
1669 | UniversalPrint(str, &ss1); | |
1670 | EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss1.str()); | |
1671 | ||
1672 | const char mutable_str[] = "\"Line\0 1\"\nLine 2"; | |
1673 | ::std::stringstream ss2; | |
1674 | UniversalPrint(mutable_str, &ss2); | |
1675 | EXPECT_EQ("\"\\\"Line\\0 1\\\"\\nLine 2\"", ss2.str()); | |
1676 | } | |
1677 | ||
1e59de90 TL |
1678 | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsEmptyTuple) { |
1679 | Strings result = UniversalTersePrintTupleFieldsToStrings(::std::make_tuple()); | |
31f18b77 FG |
1680 | EXPECT_EQ(0u, result.size()); |
1681 | } | |
1682 | ||
1e59de90 | 1683 | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsOneTuple) { |
31f18b77 | 1684 | Strings result = UniversalTersePrintTupleFieldsToStrings( |
1e59de90 | 1685 | ::std::make_tuple(1)); |
31f18b77 FG |
1686 | ASSERT_EQ(1u, result.size()); |
1687 | EXPECT_EQ("1", result[0]); | |
1688 | } | |
1689 | ||
1e59de90 | 1690 | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTwoTuple) { |
31f18b77 | 1691 | Strings result = UniversalTersePrintTupleFieldsToStrings( |
1e59de90 | 1692 | ::std::make_tuple(1, 'a')); |
31f18b77 FG |
1693 | ASSERT_EQ(2u, result.size()); |
1694 | EXPECT_EQ("1", result[0]); | |
1695 | EXPECT_EQ("'a' (97, 0x61)", result[1]); | |
1696 | } | |
1697 | ||
1e59de90 | 1698 | TEST(UniversalTersePrintTupleFieldsToStringsTestWithStd, PrintsTersely) { |
31f18b77 FG |
1699 | const int n = 1; |
1700 | Strings result = UniversalTersePrintTupleFieldsToStrings( | |
1e59de90 | 1701 | ::std::tuple<const int&, const char*>(n, "a")); |
31f18b77 FG |
1702 | ASSERT_EQ(2u, result.size()); |
1703 | EXPECT_EQ("1", result[0]); | |
1704 | EXPECT_EQ("\"a\"", result[1]); | |
1705 | } | |
1706 | ||
1e59de90 TL |
1707 | #if GTEST_INTERNAL_HAS_ANY |
1708 | class PrintAnyTest : public ::testing::Test { | |
1709 | protected: | |
1710 | template <typename T> | |
1711 | static std::string ExpectedTypeName() { | |
1712 | #if GTEST_HAS_RTTI | |
1713 | return internal::GetTypeName<T>(); | |
1714 | #else | |
1715 | return "<unknown_type>"; | |
1716 | #endif // GTEST_HAS_RTTI | |
1717 | } | |
1718 | }; | |
31f18b77 | 1719 | |
1e59de90 TL |
1720 | TEST_F(PrintAnyTest, Empty) { |
1721 | internal::Any any; | |
1722 | EXPECT_EQ("no value", PrintToString(any)); | |
31f18b77 FG |
1723 | } |
1724 | ||
1e59de90 TL |
1725 | TEST_F(PrintAnyTest, NonEmpty) { |
1726 | internal::Any any; | |
1727 | constexpr int val1 = 10; | |
1728 | const std::string val2 = "content"; | |
1729 | ||
1730 | any = val1; | |
1731 | EXPECT_EQ("value of type " + ExpectedTypeName<int>(), PrintToString(any)); | |
1732 | ||
1733 | any = val2; | |
1734 | EXPECT_EQ("value of type " + ExpectedTypeName<std::string>(), | |
1735 | PrintToString(any)); | |
31f18b77 | 1736 | } |
1e59de90 | 1737 | #endif // GTEST_INTERNAL_HAS_ANY |
31f18b77 | 1738 | |
1e59de90 TL |
1739 | #if GTEST_INTERNAL_HAS_OPTIONAL |
1740 | TEST(PrintOptionalTest, Basic) { | |
1741 | internal::Optional<int> value; | |
1742 | EXPECT_EQ("(nullopt)", PrintToString(value)); | |
1743 | value = {7}; | |
1744 | EXPECT_EQ("(7)", PrintToString(value)); | |
1745 | EXPECT_EQ("(1.1)", PrintToString(internal::Optional<double>{1.1})); | |
1746 | EXPECT_EQ("(\"A\")", PrintToString(internal::Optional<std::string>{"A"})); | |
31f18b77 | 1747 | } |
1e59de90 | 1748 | #endif // GTEST_INTERNAL_HAS_OPTIONAL |
31f18b77 | 1749 | |
1e59de90 TL |
1750 | #if GTEST_INTERNAL_HAS_VARIANT |
1751 | struct NonPrintable { | |
1752 | unsigned char contents = 17; | |
1753 | }; | |
1754 | ||
1755 | TEST(PrintOneofTest, Basic) { | |
1756 | using Type = internal::Variant<int, StreamableInGlobal, NonPrintable>; | |
1757 | EXPECT_EQ("('int(index = 0)' with value 7)", PrintToString(Type(7))); | |
1758 | EXPECT_EQ("('StreamableInGlobal(index = 1)' with value StreamableInGlobal)", | |
1759 | PrintToString(Type(StreamableInGlobal{}))); | |
1760 | EXPECT_EQ( | |
1761 | "('testing::gtest_printers_test::NonPrintable(index = 2)' with value " | |
1762 | "1-byte object <11>)", | |
1763 | PrintToString(Type(NonPrintable{}))); | |
1764 | } | |
1765 | #endif // GTEST_INTERNAL_HAS_VARIANT | |
1766 | namespace { | |
1767 | class string_ref; | |
1768 | ||
1769 | /** | |
1770 | * This is a synthetic pointer to a fixed size string. | |
1771 | */ | |
1772 | class string_ptr { | |
1773 | public: | |
1774 | string_ptr(const char* data, size_t size) : data_(data), size_(size) {} | |
1775 | ||
1776 | string_ptr& operator++() noexcept { | |
1777 | data_ += size_; | |
1778 | return *this; | |
1779 | } | |
1780 | ||
1781 | string_ref operator*() const noexcept; | |
1782 | ||
1783 | private: | |
1784 | const char* data_; | |
1785 | size_t size_; | |
1786 | }; | |
1787 | ||
1788 | /** | |
1789 | * This is a synthetic reference of a fixed size string. | |
1790 | */ | |
1791 | class string_ref { | |
1792 | public: | |
1793 | string_ref(const char* data, size_t size) : data_(data), size_(size) {} | |
1794 | ||
1795 | string_ptr operator&() const noexcept { return {data_, size_}; } // NOLINT | |
1796 | ||
1797 | bool operator==(const char* s) const noexcept { | |
1798 | if (size_ > 0 && data_[size_ - 1] != 0) { | |
1799 | return std::string(data_, size_) == std::string(s); | |
1800 | } else { | |
1801 | return std::string(data_) == std::string(s); | |
1802 | } | |
1803 | } | |
1804 | ||
1805 | private: | |
1806 | const char* data_; | |
1807 | size_t size_; | |
1808 | }; | |
1809 | ||
1810 | string_ref string_ptr::operator*() const noexcept { return {data_, size_}; } | |
1811 | ||
1812 | TEST(string_ref, compare) { | |
1813 | const char* s = "alex\0davidjohn\0"; | |
1814 | string_ptr ptr(s, 5); | |
1815 | EXPECT_EQ(*ptr, "alex"); | |
1816 | EXPECT_TRUE(*ptr == "alex"); | |
1817 | ++ptr; | |
1818 | EXPECT_EQ(*ptr, "david"); | |
1819 | EXPECT_TRUE(*ptr == "david"); | |
1820 | ++ptr; | |
1821 | EXPECT_EQ(*ptr, "john"); | |
31f18b77 FG |
1822 | } |
1823 | ||
1e59de90 | 1824 | } // namespace |
31f18b77 FG |
1825 | |
1826 | } // namespace gtest_printers_test | |
1827 | } // namespace testing |