OLD | NEW |
| (Empty) |
1 /* | |
2 * Copyright 2015 The WebRTC Project Authors. All rights reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include <memory> | |
12 #include <sstream> | |
13 #include <string> | |
14 #include <utility> | |
15 #include <vector> | |
16 | |
17 #include "webrtc/base/gunit.h" | |
18 #include "webrtc/base/optional.h" | |
19 | |
20 namespace rtc { | |
21 | |
22 namespace { | |
23 | |
24 struct MyUnprintableType { | |
25 int value; | |
26 }; | |
27 | |
28 struct MyPrintableType { | |
29 int value; | |
30 }; | |
31 | |
32 struct MyOstreamPrintableType { | |
33 int value; | |
34 }; | |
35 | |
36 void PrintTo(const MyPrintableType& mpt, std::ostream* os) { | |
37 *os << "The value is " << mpt.value; | |
38 } | |
39 | |
40 std::ostream& operator<<(std::ostream& os, | |
41 const MyPrintableType& mpt) { | |
42 os << mpt.value; | |
43 return os; | |
44 } | |
45 | |
46 std::ostream& operator<<(std::ostream& os, | |
47 const MyOstreamPrintableType& mpt) { | |
48 os << mpt.value; | |
49 return os; | |
50 } | |
51 | |
52 // Class whose instances logs various method calls (constructor, destructor, | |
53 // etc.). Each instance has a unique ID (a simple global sequence number) and | |
54 // an origin ID. When a copy is made, the new object gets a fresh ID but copies | |
55 // the origin ID from the original. When a new Logger is created from scratch, | |
56 // it gets a fresh ID, and the origin ID is the same as the ID (default | |
57 // constructor) or given as an argument (explicit constructor). | |
58 class Logger { | |
59 public: | |
60 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); } | |
61 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) { | |
62 Log("explicit constructor"); | |
63 } | |
64 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value) | |
65 : id_(g_next_id++), origin_(origin) { | |
66 Log("multi parameter constructor"); | |
67 } | |
68 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) { | |
69 LogFrom("copy constructor", other); | |
70 } | |
71 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) { | |
72 LogFrom("move constructor", other); | |
73 } | |
74 ~Logger() { Log("destructor"); } | |
75 Logger& operator=(const Logger& other) { | |
76 origin_ = other.origin_; | |
77 LogFrom("operator= copy", other); | |
78 return *this; | |
79 } | |
80 Logger& operator=(Logger&& other) { | |
81 origin_ = other.origin_; | |
82 LogFrom("operator= move", other); | |
83 return *this; | |
84 } | |
85 friend void swap(Logger& a, Logger& b) { | |
86 using std::swap; | |
87 swap(a.origin_, b.origin_); | |
88 Log2("swap", a, b); | |
89 } | |
90 friend bool operator==(const Logger& a, const Logger& b) { | |
91 Log2("operator==", a, b); | |
92 return a.origin_ == b.origin_; | |
93 } | |
94 friend bool operator!=(const Logger& a, const Logger& b) { | |
95 Log2("operator!=", a, b); | |
96 return a.origin_ != b.origin_; | |
97 } | |
98 void Foo() { Log("Foo()"); } | |
99 void Foo() const { Log("Foo() const"); } | |
100 static std::unique_ptr<std::vector<std::string>> Setup() { | |
101 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>); | |
102 g_log = s.get(); | |
103 g_next_id = 0; | |
104 return s; | |
105 } | |
106 | |
107 private: | |
108 int id_; | |
109 int origin_; | |
110 static std::vector<std::string>* g_log; | |
111 static int g_next_id; | |
112 void Log(const char* msg) const { | |
113 std::ostringstream oss; | |
114 oss << id_ << ':' << origin_ << ". " << msg; | |
115 g_log->push_back(oss.str()); | |
116 } | |
117 void LogFrom(const char* msg, const Logger& other) const { | |
118 std::ostringstream oss; | |
119 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':' | |
120 << other.origin_ << ")"; | |
121 g_log->push_back(oss.str()); | |
122 } | |
123 static void Log2(const char* msg, const Logger& a, const Logger& b) { | |
124 std::ostringstream oss; | |
125 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':' | |
126 << b.origin_; | |
127 g_log->push_back(oss.str()); | |
128 } | |
129 }; | |
130 | |
131 std::vector<std::string>* Logger::g_log = nullptr; | |
132 int Logger::g_next_id = 0; | |
133 | |
134 // Append all the other args to the vector pointed to by the first arg. | |
135 template <typename T> | |
136 void VectorAppend(std::vector<T>* v) {} | |
137 template <typename T, typename... Ts> | |
138 void VectorAppend(std::vector<T>* v, const T& e, Ts... es) { | |
139 v->push_back(e); | |
140 VectorAppend(v, es...); | |
141 } | |
142 | |
143 // Create a vector of strings. Because we're not allowed to use | |
144 // std::initializer_list. | |
145 template <typename... Ts> | |
146 std::vector<std::string> V(Ts... es) { | |
147 std::vector<std::string> strings; | |
148 VectorAppend(&strings, static_cast<std::string>(es)...); | |
149 return strings; | |
150 } | |
151 | |
152 } // namespace | |
153 | |
154 TEST(OptionalTest, TestConstructDefault) { | |
155 auto log = Logger::Setup(); | |
156 { | |
157 Optional<Logger> x; | |
158 EXPECT_FALSE(x); | |
159 EXPECT_FALSE(x.has_value()); | |
160 } | |
161 EXPECT_EQ(V(), *log); | |
162 } | |
163 | |
164 TEST(OptionalTest, TestConstructCopyEmpty) { | |
165 auto log = Logger::Setup(); | |
166 { | |
167 Optional<Logger> x; | |
168 EXPECT_FALSE(x); | |
169 EXPECT_FALSE(x.has_value()); | |
170 auto y = x; | |
171 EXPECT_FALSE(y); | |
172 EXPECT_FALSE(y.has_value()); | |
173 } | |
174 EXPECT_EQ(V(), *log); | |
175 } | |
176 | |
177 TEST(OptionalTest, TestConstructCopyFull) { | |
178 auto log = Logger::Setup(); | |
179 { | |
180 Logger a; | |
181 Optional<Logger> x(a); | |
182 EXPECT_TRUE(x); | |
183 EXPECT_TRUE(x.has_value()); | |
184 log->push_back("---"); | |
185 auto y = x; | |
186 EXPECT_TRUE(y); | |
187 EXPECT_TRUE(y.has_value()); | |
188 log->push_back("---"); | |
189 } | |
190 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)", | |
191 "---", "2:0. copy constructor (from 1:0)", "---", | |
192 "2:0. destructor", "1:0. destructor", "0:0. destructor"), | |
193 *log); | |
194 } | |
195 | |
196 TEST(OptionalTest, TestConstructMoveEmpty) { | |
197 auto log = Logger::Setup(); | |
198 { | |
199 Optional<Logger> x; | |
200 EXPECT_FALSE(x); | |
201 EXPECT_FALSE(x.has_value()); | |
202 auto y = std::move(x); | |
203 EXPECT_FALSE(y); | |
204 EXPECT_FALSE(y.has_value()); | |
205 } | |
206 EXPECT_EQ(V(), *log); | |
207 } | |
208 | |
209 TEST(OptionalTest, TestConstructMoveFull) { | |
210 auto log = Logger::Setup(); | |
211 { | |
212 Optional<Logger> x(Logger(17)); | |
213 EXPECT_TRUE(x); | |
214 EXPECT_TRUE(x.has_value()); | |
215 log->push_back("---"); | |
216 auto y = std::move(x); | |
217 EXPECT_TRUE(x); | |
218 EXPECT_TRUE(x.has_value()); | |
219 EXPECT_TRUE(y); | |
220 EXPECT_TRUE(y.has_value()); | |
221 log->push_back("---"); | |
222 } | |
223 EXPECT_EQ( | |
224 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
225 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---", | |
226 "2:17. destructor", "1:17. destructor"), | |
227 *log); | |
228 } | |
229 | |
230 TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) { | |
231 auto log = Logger::Setup(); | |
232 { | |
233 Optional<Logger> x, y; | |
234 x = y; | |
235 } | |
236 EXPECT_EQ(V(), *log); | |
237 } | |
238 | |
239 TEST(OptionalTest, TestCopyAssignToFullFromEmpty) { | |
240 auto log = Logger::Setup(); | |
241 { | |
242 Optional<Logger> x(Logger(17)); | |
243 Optional<Logger> y; | |
244 log->push_back("---"); | |
245 x = y; | |
246 log->push_back("---"); | |
247 } | |
248 EXPECT_EQ( | |
249 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
250 "0:17. destructor", "---", "1:17. destructor", "---"), | |
251 *log); | |
252 } | |
253 | |
254 TEST(OptionalTest, TestCopyAssignToEmptyFromFull) { | |
255 auto log = Logger::Setup(); | |
256 { | |
257 Optional<Logger> x; | |
258 Optional<Logger> y(Logger(17)); | |
259 log->push_back("---"); | |
260 x = y; | |
261 log->push_back("---"); | |
262 } | |
263 EXPECT_EQ( | |
264 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
265 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---", | |
266 "1:17. destructor", "2:17. destructor"), | |
267 *log); | |
268 } | |
269 | |
270 TEST(OptionalTest, TestCopyAssignToFullFromFull) { | |
271 auto log = Logger::Setup(); | |
272 { | |
273 Optional<Logger> x(Logger(17)); | |
274 Optional<Logger> y(Logger(42)); | |
275 log->push_back("---"); | |
276 x = y; | |
277 log->push_back("---"); | |
278 } | |
279 EXPECT_EQ( | |
280 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
281 "0:17. destructor", "2:42. explicit constructor", | |
282 "3:42. move constructor (from 2:42)", "2:42. destructor", "---", | |
283 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor", | |
284 "1:42. destructor"), | |
285 *log); | |
286 } | |
287 | |
288 TEST(OptionalTest, TestCopyAssignToEmptyFromT) { | |
289 auto log = Logger::Setup(); | |
290 { | |
291 Optional<Logger> x; | |
292 Logger y(17); | |
293 log->push_back("---"); | |
294 x = Optional<Logger>(y); | |
295 log->push_back("---"); | |
296 } | |
297 EXPECT_EQ(V("0:17. explicit constructor", "---", | |
298 "1:17. copy constructor (from 0:17)", | |
299 "2:17. move constructor (from 1:17)", "1:17. destructor", "---", | |
300 "0:17. destructor", "2:17. destructor"), | |
301 *log); | |
302 } | |
303 | |
304 TEST(OptionalTest, TestCopyAssignToFullFromT) { | |
305 auto log = Logger::Setup(); | |
306 { | |
307 Optional<Logger> x(Logger(17)); | |
308 Logger y(42); | |
309 log->push_back("---"); | |
310 x = Optional<Logger>(y); | |
311 log->push_back("---"); | |
312 } | |
313 EXPECT_EQ( | |
314 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
315 "0:17. destructor", "2:42. explicit constructor", "---", | |
316 "3:42. copy constructor (from 2:42)", | |
317 "1:42. operator= move (from 3:42)", "3:42. destructor", "---", | |
318 "2:42. destructor", "1:42. destructor"), | |
319 *log); | |
320 } | |
321 | |
322 TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) { | |
323 auto log = Logger::Setup(); | |
324 { | |
325 Optional<Logger> x, y; | |
326 x = std::move(y); | |
327 } | |
328 EXPECT_EQ(V(), *log); | |
329 } | |
330 | |
331 TEST(OptionalTest, TestMoveAssignToFullFromEmpty) { | |
332 auto log = Logger::Setup(); | |
333 { | |
334 Optional<Logger> x(Logger(17)); | |
335 Optional<Logger> y; | |
336 log->push_back("---"); | |
337 x = std::move(y); | |
338 log->push_back("---"); | |
339 } | |
340 EXPECT_EQ( | |
341 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
342 "0:17. destructor", "---", "1:17. destructor", "---"), | |
343 *log); | |
344 } | |
345 | |
346 TEST(OptionalTest, TestMoveAssignToEmptyFromFull) { | |
347 auto log = Logger::Setup(); | |
348 { | |
349 Optional<Logger> x; | |
350 Optional<Logger> y(Logger(17)); | |
351 log->push_back("---"); | |
352 x = std::move(y); | |
353 log->push_back("---"); | |
354 } | |
355 EXPECT_EQ( | |
356 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
357 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---", | |
358 "1:17. destructor", "2:17. destructor"), | |
359 *log); | |
360 } | |
361 | |
362 TEST(OptionalTest, TestMoveAssignToFullFromFull) { | |
363 auto log = Logger::Setup(); | |
364 { | |
365 Optional<Logger> x(Logger(17)); | |
366 Optional<Logger> y(Logger(42)); | |
367 log->push_back("---"); | |
368 x = std::move(y); | |
369 log->push_back("---"); | |
370 } | |
371 EXPECT_EQ( | |
372 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
373 "0:17. destructor", "2:42. explicit constructor", | |
374 "3:42. move constructor (from 2:42)", "2:42. destructor", "---", | |
375 "1:42. operator= move (from 3:42)", "---", "3:42. destructor", | |
376 "1:42. destructor"), | |
377 *log); | |
378 } | |
379 | |
380 TEST(OptionalTest, TestMoveAssignToEmptyFromT) { | |
381 auto log = Logger::Setup(); | |
382 { | |
383 Optional<Logger> x; | |
384 Logger y(17); | |
385 log->push_back("---"); | |
386 x = Optional<Logger>(std::move(y)); | |
387 log->push_back("---"); | |
388 } | |
389 EXPECT_EQ(V("0:17. explicit constructor", "---", | |
390 "1:17. move constructor (from 0:17)", | |
391 "2:17. move constructor (from 1:17)", "1:17. destructor", "---", | |
392 "0:17. destructor", "2:17. destructor"), | |
393 *log); | |
394 } | |
395 | |
396 TEST(OptionalTest, TestMoveAssignToFullFromT) { | |
397 auto log = Logger::Setup(); | |
398 { | |
399 Optional<Logger> x(Logger(17)); | |
400 Logger y(42); | |
401 log->push_back("---"); | |
402 x = Optional<Logger>(std::move(y)); | |
403 log->push_back("---"); | |
404 } | |
405 EXPECT_EQ( | |
406 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
407 "0:17. destructor", "2:42. explicit constructor", "---", | |
408 "3:42. move constructor (from 2:42)", | |
409 "1:42. operator= move (from 3:42)", "3:42. destructor", "---", | |
410 "2:42. destructor", "1:42. destructor"), | |
411 *log); | |
412 } | |
413 | |
414 TEST(OptionalTest, TestResetEmpty) { | |
415 auto log = Logger::Setup(); | |
416 { | |
417 Optional<Logger> x; | |
418 x.reset(); | |
419 } | |
420 EXPECT_EQ(V(), *log); | |
421 } | |
422 | |
423 TEST(OptionalTest, TestResetFull) { | |
424 auto log = Logger::Setup(); | |
425 { | |
426 Optional<Logger> x(Logger(17)); | |
427 log->push_back("---"); | |
428 x.reset(); | |
429 log->push_back("---"); | |
430 } | |
431 EXPECT_EQ( | |
432 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)", | |
433 "0:17. destructor", "---", "1:17. destructor", "---"), | |
434 *log); | |
435 } | |
436 | |
437 TEST(OptionalTest, TestEmplaceEmptyWithExplicit) { | |
438 auto log = Logger::Setup(); | |
439 { | |
440 Optional<Logger> x; | |
441 log->push_back("---"); | |
442 x.emplace(42); | |
443 log->push_back("---"); | |
444 } | |
445 // clang-format off | |
446 EXPECT_EQ(V("---", | |
447 "0:42. explicit constructor", | |
448 "---", | |
449 "0:42. destructor"), | |
450 *log); | |
451 // clang-format on | |
452 } | |
453 | |
454 TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) { | |
455 auto log = Logger::Setup(); | |
456 { | |
457 Optional<Logger> x; | |
458 Logger ref(21); | |
459 Logger value(35); | |
460 log->push_back("---"); | |
461 x.emplace(42, ref, std::move(value)); | |
462 log->push_back("---"); | |
463 } | |
464 // clang-format off | |
465 EXPECT_EQ(V("0:21. explicit constructor", | |
466 "1:35. explicit constructor", | |
467 "---", | |
468 "2:35. move constructor (from 1:35)", | |
469 "3:42. multi parameter constructor", | |
470 "2:35. destructor", | |
471 "---", | |
472 "1:35. destructor", | |
473 "0:21. destructor", | |
474 "3:42. destructor"), | |
475 *log); | |
476 // clang-format on | |
477 } | |
478 | |
479 TEST(OptionalTest, TestEmplaceEmptyWithCopy) { | |
480 auto log = Logger::Setup(); | |
481 { | |
482 Optional<Logger> x; | |
483 Logger y(42); | |
484 log->push_back("---"); | |
485 x.emplace(y); | |
486 log->push_back("---"); | |
487 } | |
488 // clang-format off | |
489 EXPECT_EQ(V("0:42. explicit constructor", | |
490 "---", | |
491 "1:42. copy constructor (from 0:42)", | |
492 "---", | |
493 "0:42. destructor", | |
494 "1:42. destructor"), | |
495 *log); | |
496 // clang-format on | |
497 } | |
498 | |
499 TEST(OptionalTest, TestEmplaceEmptyWithMove) { | |
500 auto log = Logger::Setup(); | |
501 { | |
502 Optional<Logger> x; | |
503 Logger y(42); | |
504 log->push_back("---"); | |
505 x.emplace(std::move(y)); | |
506 log->push_back("---"); | |
507 } | |
508 // clang-format off | |
509 EXPECT_EQ(V("0:42. explicit constructor", | |
510 "---", | |
511 "1:42. move constructor (from 0:42)", | |
512 "---", | |
513 "0:42. destructor", | |
514 "1:42. destructor"), | |
515 *log); | |
516 // clang-format on | |
517 } | |
518 | |
519 TEST(OptionalTest, TestEmplaceFullWithExplicit) { | |
520 auto log = Logger::Setup(); | |
521 { | |
522 Optional<Logger> x(Logger(17)); | |
523 log->push_back("---"); | |
524 x.emplace(42); | |
525 log->push_back("---"); | |
526 } | |
527 // clang-format off | |
528 EXPECT_EQ( | |
529 V("0:17. explicit constructor", | |
530 "1:17. move constructor (from 0:17)", | |
531 "0:17. destructor", | |
532 "---", | |
533 "1:17. destructor", | |
534 "2:42. explicit constructor", | |
535 "---", | |
536 "2:42. destructor"), | |
537 *log); | |
538 // clang-format on | |
539 } | |
540 | |
541 TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) { | |
542 auto log = Logger::Setup(); | |
543 { | |
544 Optional<Logger> x(Logger(17)); | |
545 Logger ref(21); | |
546 Logger value(35); | |
547 log->push_back("---"); | |
548 x.emplace(42, ref, std::move(value)); | |
549 log->push_back("---"); | |
550 } | |
551 // clang-format off | |
552 EXPECT_EQ(V("0:17. explicit constructor", | |
553 "1:17. move constructor (from 0:17)", | |
554 "0:17. destructor", | |
555 "2:21. explicit constructor", | |
556 "3:35. explicit constructor", | |
557 "---", | |
558 "1:17. destructor", | |
559 "4:35. move constructor (from 3:35)", | |
560 "5:42. multi parameter constructor", | |
561 "4:35. destructor", | |
562 "---", | |
563 "3:35. destructor", | |
564 "2:21. destructor", | |
565 "5:42. destructor"), | |
566 *log); | |
567 // clang-format on | |
568 } | |
569 | |
570 TEST(OptionalTest, TestEmplaceFullWithCopy) { | |
571 auto log = Logger::Setup(); | |
572 { | |
573 Optional<Logger> x(Logger(17)); | |
574 Logger y(42); | |
575 log->push_back("---"); | |
576 x.emplace(y); | |
577 log->push_back("---"); | |
578 } | |
579 // clang-format off | |
580 EXPECT_EQ(V("0:17. explicit constructor", | |
581 "1:17. move constructor (from 0:17)", | |
582 "0:17. destructor", | |
583 "2:42. explicit constructor", | |
584 "---", | |
585 "1:17. destructor", | |
586 "3:42. copy constructor (from 2:42)", | |
587 "---", | |
588 "2:42. destructor", | |
589 "3:42. destructor"), | |
590 *log); | |
591 // clang-format on | |
592 } | |
593 | |
594 TEST(OptionalTest, TestEmplaceFullWithMove) { | |
595 auto log = Logger::Setup(); | |
596 { | |
597 Optional<Logger> x(Logger(17)); | |
598 Logger y(42); | |
599 log->push_back("---"); | |
600 x.emplace(std::move(y)); | |
601 log->push_back("---"); | |
602 } | |
603 // clang-format off | |
604 EXPECT_EQ(V("0:17. explicit constructor", | |
605 "1:17. move constructor (from 0:17)", | |
606 "0:17. destructor", | |
607 "2:42. explicit constructor", | |
608 "---", | |
609 "1:17. destructor", | |
610 "3:42. move constructor (from 2:42)", | |
611 "---", | |
612 "2:42. destructor", | |
613 "3:42. destructor"), | |
614 *log); | |
615 // clang-format on | |
616 } | |
617 | |
618 TEST(OptionalTest, TestDereference) { | |
619 auto log = Logger::Setup(); | |
620 { | |
621 Optional<Logger> x(Logger(42)); | |
622 const auto& y = x; | |
623 log->push_back("---"); | |
624 x->Foo(); | |
625 y->Foo(); | |
626 std::move(x)->Foo(); | |
627 std::move(y)->Foo(); | |
628 log->push_back("---"); | |
629 (*x).Foo(); | |
630 (*y).Foo(); | |
631 (*std::move(x)).Foo(); | |
632 (*std::move(y)).Foo(); | |
633 log->push_back("---"); | |
634 x.value().Foo(); | |
635 y.value().Foo(); | |
636 std::move(x).value().Foo(); | |
637 std::move(y).value().Foo(); | |
638 log->push_back("---"); | |
639 } | |
640 // clang-format off | |
641 EXPECT_EQ(V("0:42. explicit constructor", | |
642 "1:42. move constructor (from 0:42)", | |
643 "0:42. destructor", | |
644 "---", | |
645 "1:42. Foo()", | |
646 "1:42. Foo() const", | |
647 "1:42. Foo()", | |
648 "1:42. Foo() const", | |
649 "---", | |
650 "1:42. Foo()", | |
651 "1:42. Foo() const", | |
652 "1:42. Foo()", | |
653 "1:42. Foo() const", | |
654 "---", | |
655 "1:42. Foo()", | |
656 "1:42. Foo() const", | |
657 "1:42. Foo()", | |
658 "1:42. Foo() const", | |
659 "---", | |
660 "1:42. destructor"), | |
661 *log); | |
662 // clang-format on | |
663 } | |
664 | |
665 TEST(OptionalTest, TestDereferenceWithDefault) { | |
666 auto log = Logger::Setup(); | |
667 { | |
668 const Logger a(17), b(42); | |
669 Optional<Logger> x(a); | |
670 Optional<Logger> y; | |
671 log->push_back("-1-"); | |
672 EXPECT_EQ(a, x.value_or(Logger(42))); | |
673 log->push_back("-2-"); | |
674 EXPECT_EQ(b, y.value_or(Logger(42))); | |
675 log->push_back("-3-"); | |
676 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b)); | |
677 log->push_back("-4-"); | |
678 EXPECT_EQ(b, Optional<Logger>().value_or(b)); | |
679 log->push_back("-5-"); | |
680 } | |
681 EXPECT_EQ( | |
682 V("0:17. explicit constructor", "1:42. explicit constructor", | |
683 "2:17. copy constructor (from 0:17)", "-1-", | |
684 "3:42. explicit constructor", "operator== 0:17, 2:17", | |
685 "3:42. destructor", "-2-", "4:42. explicit constructor", | |
686 "operator== 1:42, 4:42", "4:42. destructor", "-3-", | |
687 "5:17. explicit constructor", "6:17. move constructor (from 5:17)", | |
688 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-", | |
689 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor", | |
690 "0:17. destructor"), | |
691 *log); | |
692 } | |
693 | |
694 TEST(OptionalTest, TestEquality) { | |
695 auto log = Logger::Setup(); | |
696 { | |
697 Logger a(17), b(42); | |
698 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2; | |
699 log->push_back("---"); | |
700 EXPECT_EQ(ma1, ma1); | |
701 EXPECT_EQ(ma1, ma2); | |
702 EXPECT_NE(ma1, mb); | |
703 EXPECT_NE(ma1, me1); | |
704 EXPECT_EQ(me1, me1); | |
705 EXPECT_EQ(me1, me2); | |
706 log->push_back("---"); | |
707 } | |
708 EXPECT_EQ( | |
709 V("0:17. explicit constructor", "1:42. explicit constructor", | |
710 "2:17. copy constructor (from 0:17)", | |
711 "3:17. copy constructor (from 0:17)", | |
712 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17", | |
713 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---", | |
714 "4:42. destructor", "3:17. destructor", "2:17. destructor", | |
715 "1:42. destructor", "0:17. destructor"), | |
716 *log); | |
717 } | |
718 | |
719 TEST(OptionalTest, TestEqualityWithObject) { | |
720 auto log = Logger::Setup(); | |
721 { | |
722 Logger a(17), b(42); | |
723 Optional<Logger> ma(a), me; | |
724 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE | |
725 // macros because those operators are under test. | |
726 log->push_back("---"); | |
727 | |
728 EXPECT_TRUE(ma == a); | |
729 EXPECT_TRUE(a == ma); | |
730 EXPECT_FALSE(ma == b); | |
731 EXPECT_FALSE(b == ma); | |
732 EXPECT_FALSE(me == a); | |
733 EXPECT_FALSE(a == me); | |
734 | |
735 EXPECT_FALSE(ma != a); | |
736 EXPECT_FALSE(a != ma); | |
737 EXPECT_TRUE(ma != b); | |
738 EXPECT_TRUE(b != ma); | |
739 EXPECT_TRUE(me != a); | |
740 EXPECT_TRUE(a != me); | |
741 | |
742 log->push_back("---"); | |
743 } | |
744 // clang-format off | |
745 EXPECT_EQ(V("0:17. explicit constructor", | |
746 "1:42. explicit constructor", | |
747 "2:17. copy constructor (from 0:17)", | |
748 "---", | |
749 "operator== 2:17, 0:17", | |
750 "operator== 0:17, 2:17", | |
751 "operator== 2:17, 1:42", | |
752 "operator== 1:42, 2:17", | |
753 // No operator should be called when comparing to empty. | |
754 "operator!= 2:17, 0:17", | |
755 "operator!= 0:17, 2:17", | |
756 "operator!= 2:17, 1:42", | |
757 "operator!= 1:42, 2:17", | |
758 // No operator should be called when comparing to empty. | |
759 "---", | |
760 "2:17. destructor", | |
761 "1:42. destructor", | |
762 "0:17. destructor"), | |
763 *log); | |
764 // clang-format on | |
765 } | |
766 | |
767 TEST(OptionalTest, TestSwap) { | |
768 auto log = Logger::Setup(); | |
769 { | |
770 Logger a(17), b(42); | |
771 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2; | |
772 log->push_back("---"); | |
773 swap(x1, x2); // Swap full <-> full. | |
774 swap(y1, y2); // Swap full <-> empty. | |
775 swap(z1, z2); // Swap empty <-> empty. | |
776 log->push_back("---"); | |
777 } | |
778 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor", | |
779 "2:17. copy constructor (from 0:17)", | |
780 "3:42. copy constructor (from 1:42)", | |
781 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17", | |
782 "5:17. move constructor (from 4:17)", "4:17. destructor", "---", | |
783 "5:17. destructor", "3:17. destructor", "2:42. destructor", | |
784 "1:42. destructor", "0:17. destructor"), | |
785 *log); | |
786 } | |
787 | |
788 TEST(OptionalTest, TestMoveValue) { | |
789 auto log = Logger::Setup(); | |
790 { | |
791 Optional<Logger> x(Logger(42)); | |
792 log->push_back("---"); | |
793 Logger moved = x.MoveValue(); | |
794 log->push_back("---"); | |
795 } | |
796 EXPECT_EQ( | |
797 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)", | |
798 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---", | |
799 "2:42. destructor", "1:42. destructor"), | |
800 *log); | |
801 } | |
802 | |
803 TEST(OptionalTest, TestPrintTo) { | |
804 constexpr char kEmptyOptionalMessage[] = "<empty optional>"; | |
805 const Optional<MyUnprintableType> empty_unprintable; | |
806 const Optional<MyPrintableType> empty_printable; | |
807 const Optional<MyOstreamPrintableType> empty_ostream_printable; | |
808 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable)); | |
809 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable)); | |
810 EXPECT_EQ(kEmptyOptionalMessage, | |
811 ::testing::PrintToString(empty_ostream_printable)); | |
812 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1}))); | |
813 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1}))); | |
814 EXPECT_EQ("The value is 1", | |
815 ::testing::PrintToString(Optional<MyPrintableType>({1}))); | |
816 EXPECT_EQ("1", | |
817 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1}))); | |
818 } | |
819 | |
820 void UnusedFunctionWorkaround() { | |
821 // These are here to ensure we don't get warnings about ostream and PrintTo | |
822 // for MyPrintableType never getting called. | |
823 const MyPrintableType dont_warn{17}; | |
824 const MyOstreamPrintableType dont_warn2{18}; | |
825 std::stringstream sstr; | |
826 sstr << dont_warn; | |
827 PrintTo(dont_warn, &sstr); | |
828 sstr << dont_warn2; | |
829 } | |
830 | |
831 } // namespace rtc | |
OLD | NEW |