blob: cc9d2f91643a53aac1a2d5dde7835c7d30b6e7be [file] [log] [blame]
Karl Wiberg6e587202015-10-21 12:43:56 +02001/*
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
jbauch555604a2016-04-26 03:13:22 -070011#include <memory>
Karl Wiberg6e587202015-10-21 12:43:56 +020012#include <sstream>
13#include <string>
14#include <utility>
15#include <vector>
16
17#include "webrtc/base/gunit.h"
Karl Wibergbe579832015-11-10 22:34:18 +010018#include "webrtc/base/optional.h"
Karl Wiberg6e587202015-10-21 12:43:56 +020019
20namespace rtc {
21
22namespace {
23
ossue5c27a52017-02-20 04:41:42 -080024struct MyUnprintableType {
25 int value;
26};
27
28struct MyPrintableType {
29 int value;
30};
31
32struct MyOstreamPrintableType {
33 int value;
34};
35
36void PrintTo(const MyPrintableType& mpt, std::ostream* os) {
37 *os << "The value is " << mpt.value;
38}
39
40std::ostream& operator<<(std::ostream& os,
41 const MyPrintableType& mpt) {
42 os << mpt.value;
43 return os;
44}
45
46std::ostream& operator<<(std::ostream& os,
47 const MyOstreamPrintableType& mpt) {
48 os << mpt.value;
49 return os;
50}
51
Karl Wiberg6e587202015-10-21 12:43:56 +020052// 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).
58class Logger {
59 public:
kwibergb2137952016-03-17 08:38:12 -070060 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
61 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020062 Log("explicit constructor");
63 }
danilchap9e83c972016-10-18 04:07:18 -070064 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 }
kwibergb2137952016-03-17 08:38:12 -070068 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020069 LogFrom("copy constructor", other);
70 }
kwibergb2137952016-03-17 08:38:12 -070071 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020072 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"); }
jbauch555604a2016-04-26 03:13:22 -0700100 static std::unique_ptr<std::vector<std::string>> Setup() {
101 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -0700102 g_log = s.get();
103 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200104 return s;
105 }
106
107 private:
108 int id_;
109 int origin_;
kwibergb2137952016-03-17 08:38:12 -0700110 static std::vector<std::string>* g_log;
111 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +0200112 void Log(const char* msg) const {
113 std::ostringstream oss;
114 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -0700115 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200116 }
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_ << ")";
kwibergb2137952016-03-17 08:38:12 -0700121 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200122 }
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_;
kwibergb2137952016-03-17 08:38:12 -0700127 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200128 }
129};
130
kwibergb2137952016-03-17 08:38:12 -0700131std::vector<std::string>* Logger::g_log = nullptr;
132int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200133
134// Append all the other args to the vector pointed to by the first arg.
135template <typename T>
136void VectorAppend(std::vector<T>* v) {}
137template <typename T, typename... Ts>
138void 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.
145template <typename... Ts>
146std::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
Karl Wibergbe579832015-11-10 22:34:18 +0100154TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200155 auto log = Logger::Setup();
156 {
Karl Wibergbe579832015-11-10 22:34:18 +0100157 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200158 EXPECT_FALSE(x);
159 }
kwibergd0404802016-05-09 06:06:05 -0700160 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200161}
162
Karl Wibergbe579832015-11-10 22:34:18 +0100163TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200164 auto log = Logger::Setup();
165 {
Karl Wibergbe579832015-11-10 22:34:18 +0100166 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200167 EXPECT_FALSE(x);
168 auto y = x;
169 EXPECT_FALSE(y);
170 }
kwibergd0404802016-05-09 06:06:05 -0700171 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200172}
173
Karl Wibergbe579832015-11-10 22:34:18 +0100174TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200175 auto log = Logger::Setup();
176 {
177 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100178 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200179 EXPECT_TRUE(x);
180 log->push_back("---");
181 auto y = x;
182 EXPECT_TRUE(y);
183 log->push_back("---");
184 }
185 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
186 "---", "2:0. copy constructor (from 1:0)", "---",
187 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
188 *log);
189}
190
Karl Wibergbe579832015-11-10 22:34:18 +0100191TEST(OptionalTest, TestConstructMoveEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200192 auto log = Logger::Setup();
193 {
Karl Wibergbe579832015-11-10 22:34:18 +0100194 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200195 EXPECT_FALSE(x);
kwibergcea7c2f2016-01-07 05:52:04 -0800196 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200197 EXPECT_FALSE(y);
198 }
kwibergd0404802016-05-09 06:06:05 -0700199 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200200}
201
Karl Wibergbe579832015-11-10 22:34:18 +0100202TEST(OptionalTest, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200203 auto log = Logger::Setup();
204 {
Karl Wibergbe579832015-11-10 22:34:18 +0100205 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200206 EXPECT_TRUE(x);
207 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800208 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200209 EXPECT_TRUE(x);
210 EXPECT_TRUE(y);
211 log->push_back("---");
212 }
213 EXPECT_EQ(
214 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
215 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
216 "2:17. destructor", "1:17. destructor"),
217 *log);
218}
219
Karl Wibergbe579832015-11-10 22:34:18 +0100220TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200221 auto log = Logger::Setup();
222 {
Karl Wibergbe579832015-11-10 22:34:18 +0100223 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200224 x = y;
225 }
kwibergd0404802016-05-09 06:06:05 -0700226 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200227}
228
Karl Wibergbe579832015-11-10 22:34:18 +0100229TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200230 auto log = Logger::Setup();
231 {
Karl Wibergbe579832015-11-10 22:34:18 +0100232 Optional<Logger> x(Logger(17));
233 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200234 log->push_back("---");
235 x = y;
236 log->push_back("---");
237 }
238 EXPECT_EQ(
239 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700240 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200241 *log);
242}
243
Karl Wibergbe579832015-11-10 22:34:18 +0100244TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200245 auto log = Logger::Setup();
246 {
Karl Wibergbe579832015-11-10 22:34:18 +0100247 Optional<Logger> x;
248 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200249 log->push_back("---");
250 x = y;
251 log->push_back("---");
252 }
kwibergd0404802016-05-09 06:06:05 -0700253 EXPECT_EQ(
254 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
255 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
256 "1:17. destructor", "2:17. destructor"),
257 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200258}
259
Karl Wibergbe579832015-11-10 22:34:18 +0100260TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200261 auto log = Logger::Setup();
262 {
Karl Wibergbe579832015-11-10 22:34:18 +0100263 Optional<Logger> x(Logger(17));
264 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200265 log->push_back("---");
266 x = y;
267 log->push_back("---");
268 }
269 EXPECT_EQ(
270 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
271 "0:17. destructor", "2:42. explicit constructor",
272 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
273 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
274 "1:42. destructor"),
275 *log);
276}
277
Karl Wibergbe579832015-11-10 22:34:18 +0100278TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200279 auto log = Logger::Setup();
280 {
Karl Wibergbe579832015-11-10 22:34:18 +0100281 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200282 Logger y(17);
283 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100284 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200285 log->push_back("---");
286 }
kwibergd0404802016-05-09 06:06:05 -0700287 EXPECT_EQ(V("0:17. explicit constructor", "---",
288 "1:17. copy constructor (from 0:17)",
289 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
290 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200291 *log);
292}
293
Karl Wibergbe579832015-11-10 22:34:18 +0100294TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200295 auto log = Logger::Setup();
296 {
Karl Wibergbe579832015-11-10 22:34:18 +0100297 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200298 Logger y(42);
299 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100300 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200301 log->push_back("---");
302 }
303 EXPECT_EQ(
304 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
305 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700306 "3:42. copy constructor (from 2:42)",
307 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
308 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200309 *log);
310}
311
Karl Wibergbe579832015-11-10 22:34:18 +0100312TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200313 auto log = Logger::Setup();
314 {
Karl Wibergbe579832015-11-10 22:34:18 +0100315 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800316 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200317 }
kwibergd0404802016-05-09 06:06:05 -0700318 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200319}
320
Karl Wibergbe579832015-11-10 22:34:18 +0100321TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200322 auto log = Logger::Setup();
323 {
Karl Wibergbe579832015-11-10 22:34:18 +0100324 Optional<Logger> x(Logger(17));
325 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200326 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800327 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200328 log->push_back("---");
329 }
330 EXPECT_EQ(
331 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700332 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200333 *log);
334}
335
Karl Wibergbe579832015-11-10 22:34:18 +0100336TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200337 auto log = Logger::Setup();
338 {
Karl Wibergbe579832015-11-10 22:34:18 +0100339 Optional<Logger> x;
340 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200341 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800342 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200343 log->push_back("---");
344 }
kwibergd0404802016-05-09 06:06:05 -0700345 EXPECT_EQ(
346 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
347 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
348 "1:17. destructor", "2:17. destructor"),
349 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200350}
351
Karl Wibergbe579832015-11-10 22:34:18 +0100352TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200353 auto log = Logger::Setup();
354 {
Karl Wibergbe579832015-11-10 22:34:18 +0100355 Optional<Logger> x(Logger(17));
356 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200357 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800358 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200359 log->push_back("---");
360 }
361 EXPECT_EQ(
362 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
363 "0:17. destructor", "2:42. explicit constructor",
364 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
365 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
366 "1:42. destructor"),
367 *log);
368}
369
Karl Wibergbe579832015-11-10 22:34:18 +0100370TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200371 auto log = Logger::Setup();
372 {
Karl Wibergbe579832015-11-10 22:34:18 +0100373 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200374 Logger y(17);
375 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800376 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200377 log->push_back("---");
378 }
kwibergd0404802016-05-09 06:06:05 -0700379 EXPECT_EQ(V("0:17. explicit constructor", "---",
380 "1:17. move constructor (from 0:17)",
381 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
382 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200383 *log);
384}
385
Karl Wibergbe579832015-11-10 22:34:18 +0100386TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200387 auto log = Logger::Setup();
388 {
Karl Wibergbe579832015-11-10 22:34:18 +0100389 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200390 Logger y(42);
391 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800392 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200393 log->push_back("---");
394 }
395 EXPECT_EQ(
396 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
397 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700398 "3:42. move constructor (from 2:42)",
399 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
400 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200401 *log);
402}
403
danilchapc4fd23c2016-10-17 07:16:54 -0700404TEST(OptionalTest, TestResetEmpty) {
405 auto log = Logger::Setup();
406 {
407 Optional<Logger> x;
408 x.reset();
409 }
410 EXPECT_EQ(V(), *log);
411}
412
413TEST(OptionalTest, TestResetFull) {
414 auto log = Logger::Setup();
415 {
416 Optional<Logger> x(Logger(17));
417 log->push_back("---");
418 x.reset();
419 log->push_back("---");
420 }
421 EXPECT_EQ(
422 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
423 "0:17. destructor", "---", "1:17. destructor", "---"),
424 *log);
425}
426
danilchap9e83c972016-10-18 04:07:18 -0700427TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
428 auto log = Logger::Setup();
429 {
430 Optional<Logger> x;
431 log->push_back("---");
432 x.emplace(42);
433 log->push_back("---");
434 }
435 // clang-format off
436 EXPECT_EQ(V("---",
437 "0:42. explicit constructor",
438 "---",
439 "0:42. destructor"),
440 *log);
441 // clang-format on
442}
443
444TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
445 auto log = Logger::Setup();
446 {
447 Optional<Logger> x;
448 Logger ref(21);
449 Logger value(35);
450 log->push_back("---");
451 x.emplace(42, ref, std::move(value));
452 log->push_back("---");
453 }
454 // clang-format off
455 EXPECT_EQ(V("0:21. explicit constructor",
456 "1:35. explicit constructor",
457 "---",
458 "2:35. move constructor (from 1:35)",
459 "3:42. multi parameter constructor",
460 "2:35. destructor",
461 "---",
462 "1:35. destructor",
463 "0:21. destructor",
464 "3:42. destructor"),
465 *log);
466 // clang-format on
467}
468
469TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
470 auto log = Logger::Setup();
471 {
472 Optional<Logger> x;
473 Logger y(42);
474 log->push_back("---");
475 x.emplace(y);
476 log->push_back("---");
477 }
478 // clang-format off
479 EXPECT_EQ(V("0:42. explicit constructor",
480 "---",
481 "1:42. copy constructor (from 0:42)",
482 "---",
483 "0:42. destructor",
484 "1:42. destructor"),
485 *log);
486 // clang-format on
487}
488
489TEST(OptionalTest, TestEmplaceEmptyWithMove) {
490 auto log = Logger::Setup();
491 {
492 Optional<Logger> x;
493 Logger y(42);
494 log->push_back("---");
495 x.emplace(std::move(y));
496 log->push_back("---");
497 }
498 // clang-format off
499 EXPECT_EQ(V("0:42. explicit constructor",
500 "---",
501 "1:42. move constructor (from 0:42)",
502 "---",
503 "0:42. destructor",
504 "1:42. destructor"),
505 *log);
506 // clang-format on
507}
508
509TEST(OptionalTest, TestEmplaceFullWithExplicit) {
510 auto log = Logger::Setup();
511 {
512 Optional<Logger> x(Logger(17));
513 log->push_back("---");
514 x.emplace(42);
515 log->push_back("---");
516 }
517 // clang-format off
518 EXPECT_EQ(
519 V("0:17. explicit constructor",
520 "1:17. move constructor (from 0:17)",
521 "0:17. destructor",
522 "---",
523 "1:17. destructor",
524 "2:42. explicit constructor",
525 "---",
526 "2:42. destructor"),
527 *log);
528 // clang-format on
529}
530
531TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
532 auto log = Logger::Setup();
533 {
534 Optional<Logger> x(Logger(17));
535 Logger ref(21);
536 Logger value(35);
537 log->push_back("---");
538 x.emplace(42, ref, std::move(value));
539 log->push_back("---");
540 }
541 // clang-format off
542 EXPECT_EQ(V("0:17. explicit constructor",
543 "1:17. move constructor (from 0:17)",
544 "0:17. destructor",
545 "2:21. explicit constructor",
546 "3:35. explicit constructor",
547 "---",
548 "1:17. destructor",
549 "4:35. move constructor (from 3:35)",
550 "5:42. multi parameter constructor",
551 "4:35. destructor",
552 "---",
553 "3:35. destructor",
554 "2:21. destructor",
555 "5:42. destructor"),
556 *log);
557 // clang-format on
558}
559
560TEST(OptionalTest, TestEmplaceFullWithCopy) {
561 auto log = Logger::Setup();
562 {
563 Optional<Logger> x(Logger(17));
564 Logger y(42);
565 log->push_back("---");
566 x.emplace(y);
567 log->push_back("---");
568 }
569 // clang-format off
570 EXPECT_EQ(V("0:17. explicit constructor",
571 "1:17. move constructor (from 0:17)",
572 "0:17. destructor",
573 "2:42. explicit constructor",
574 "---",
575 "1:17. destructor",
576 "3:42. copy constructor (from 2:42)",
577 "---",
578 "2:42. destructor",
579 "3:42. destructor"),
580 *log);
581 // clang-format on
582}
583
584TEST(OptionalTest, TestEmplaceFullWithMove) {
585 auto log = Logger::Setup();
586 {
587 Optional<Logger> x(Logger(17));
588 Logger y(42);
589 log->push_back("---");
590 x.emplace(std::move(y));
591 log->push_back("---");
592 }
593 // clang-format off
594 EXPECT_EQ(V("0:17. explicit constructor",
595 "1:17. move constructor (from 0:17)",
596 "0:17. destructor",
597 "2:42. explicit constructor",
598 "---",
599 "1:17. destructor",
600 "3:42. move constructor (from 2:42)",
601 "---",
602 "2:42. destructor",
603 "3:42. destructor"),
604 *log);
605 // clang-format on
606}
607
Karl Wibergbe579832015-11-10 22:34:18 +0100608TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200609 auto log = Logger::Setup();
610 {
Karl Wibergbe579832015-11-10 22:34:18 +0100611 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200612 const auto& y = x;
613 log->push_back("---");
614 x->Foo();
615 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800616 std::move(x)->Foo();
617 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200618 log->push_back("---");
619 (*x).Foo();
620 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800621 (*std::move(x)).Foo();
622 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200623 log->push_back("---");
624 }
625 EXPECT_EQ(V("0:42. explicit constructor",
626 "1:42. move constructor (from 0:42)", "0:42. destructor", "---",
627 "1:42. Foo()", "1:42. Foo() const", "1:42. Foo()",
628 "1:42. Foo() const", "---", "1:42. Foo()", "1:42. Foo() const",
629 "1:42. Foo()", "1:42. Foo() const", "---", "1:42. destructor"),
630 *log);
631}
632
Karl Wibergbe579832015-11-10 22:34:18 +0100633TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200634 auto log = Logger::Setup();
635 {
636 const Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100637 Optional<Logger> x(a);
638 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200639 log->push_back("-1-");
640 EXPECT_EQ(a, x.value_or(Logger(42)));
641 log->push_back("-2-");
642 EXPECT_EQ(b, y.value_or(Logger(42)));
643 log->push_back("-3-");
Karl Wibergbe579832015-11-10 22:34:18 +0100644 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200645 log->push_back("-4-");
Karl Wibergbe579832015-11-10 22:34:18 +0100646 EXPECT_EQ(b, Optional<Logger>().value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200647 log->push_back("-5-");
648 }
649 EXPECT_EQ(
650 V("0:17. explicit constructor", "1:42. explicit constructor",
kwibergd0404802016-05-09 06:06:05 -0700651 "2:17. copy constructor (from 0:17)", "-1-",
652 "3:42. explicit constructor", "operator== 0:17, 2:17",
653 "3:42. destructor", "-2-", "4:42. explicit constructor",
654 "operator== 1:42, 4:42", "4:42. destructor", "-3-",
655 "5:17. explicit constructor", "6:17. move constructor (from 5:17)",
656 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-",
657 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200658 "0:17. destructor"),
659 *log);
660}
661
Karl Wibergbe579832015-11-10 22:34:18 +0100662TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200663 auto log = Logger::Setup();
664 {
665 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100666 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200667 log->push_back("---");
668 EXPECT_EQ(ma1, ma1);
669 EXPECT_EQ(ma1, ma2);
670 EXPECT_NE(ma1, mb);
671 EXPECT_NE(ma1, me1);
672 EXPECT_EQ(me1, me1);
673 EXPECT_EQ(me1, me2);
674 log->push_back("---");
675 }
kwibergd0404802016-05-09 06:06:05 -0700676 EXPECT_EQ(
677 V("0:17. explicit constructor", "1:42. explicit constructor",
678 "2:17. copy constructor (from 0:17)",
679 "3:17. copy constructor (from 0:17)",
680 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
681 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
682 "4:42. destructor", "3:17. destructor", "2:17. destructor",
683 "1:42. destructor", "0:17. destructor"),
684 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200685}
686
danilchape0370602016-10-20 00:58:15 -0700687TEST(OptionalTest, TestEqualityWithObject) {
688 auto log = Logger::Setup();
689 {
690 Logger a(17), b(42);
691 Optional<Logger> ma(a), me;
692 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE
693 // macros because those operators are under test.
694 log->push_back("---");
695
696 EXPECT_TRUE(ma == a);
697 EXPECT_TRUE(a == ma);
698 EXPECT_FALSE(ma == b);
699 EXPECT_FALSE(b == ma);
700 EXPECT_FALSE(me == a);
701 EXPECT_FALSE(a == me);
702
703 EXPECT_FALSE(ma != a);
704 EXPECT_FALSE(a != ma);
705 EXPECT_TRUE(ma != b);
706 EXPECT_TRUE(b != ma);
707 EXPECT_TRUE(me != a);
708 EXPECT_TRUE(a != me);
709
710 log->push_back("---");
711 }
712 // clang-format off
713 EXPECT_EQ(V("0:17. explicit constructor",
714 "1:42. explicit constructor",
715 "2:17. copy constructor (from 0:17)",
716 "---",
717 "operator== 2:17, 0:17",
718 "operator== 0:17, 2:17",
719 "operator== 2:17, 1:42",
720 "operator== 1:42, 2:17",
721 // No operator should be called when comparing to empty.
722 "operator!= 2:17, 0:17",
723 "operator!= 0:17, 2:17",
724 "operator!= 2:17, 1:42",
725 "operator!= 1:42, 2:17",
726 // No operator should be called when comparing to empty.
727 "---",
728 "2:17. destructor",
729 "1:42. destructor",
730 "0:17. destructor"),
731 *log);
732 // clang-format on
733}
734
Karl Wibergbe579832015-11-10 22:34:18 +0100735TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200736 auto log = Logger::Setup();
737 {
738 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100739 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200740 log->push_back("---");
741 swap(x1, x2); // Swap full <-> full.
742 swap(y1, y2); // Swap full <-> empty.
743 swap(z1, z2); // Swap empty <-> empty.
744 log->push_back("---");
745 }
746 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
747 "2:17. copy constructor (from 0:17)",
748 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700749 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
750 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
751 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200752 "1:42. destructor", "0:17. destructor"),
753 *log);
754}
755
deadbeef81baed32017-02-10 18:11:11 -0800756TEST(OptionalTest, TestMoveValue) {
757 auto log = Logger::Setup();
758 {
759 Optional<Logger> x(Logger(42));
760 log->push_back("---");
761 Logger moved = x.MoveValue();
762 log->push_back("---");
763 }
764 EXPECT_EQ(
765 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)",
766 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---",
767 "2:42. destructor", "1:42. destructor"),
768 *log);
769}
770
ossue5c27a52017-02-20 04:41:42 -0800771TEST(OptionalTest, TestPrintTo) {
772 constexpr char kEmptyOptionalMessage[] = "<empty optional>";
773 const Optional<MyUnprintableType> empty_unprintable;
774 const Optional<MyPrintableType> empty_printable;
775 const Optional<MyOstreamPrintableType> empty_ostream_printable;
776 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable));
777 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable));
778 EXPECT_EQ(kEmptyOptionalMessage,
779 ::testing::PrintToString(empty_ostream_printable));
780 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1})));
781 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1})));
782 EXPECT_EQ("The value is 1",
783 ::testing::PrintToString(Optional<MyPrintableType>({1})));
784 EXPECT_EQ("1",
785 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1})));
786}
787
788void UnusedFunctionWorkaround() {
789 // These are here to ensure we don't get warnings about ostream and PrintTo
790 // for MyPrintableType never getting called.
791 const MyPrintableType dont_warn{17};
792 const MyOstreamPrintableType dont_warn2{18};
793 std::stringstream sstr;
794 sstr << dont_warn;
795 PrintTo(dont_warn, &sstr);
796 sstr << dont_warn2;
797}
798
Karl Wiberg6e587202015-10-21 12:43:56 +0200799} // namespace rtc