blob: c1ae9c00d42fc4bc626595f7c8245e6801137585 [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
24// Class whose instances logs various method calls (constructor, destructor,
25// etc.). Each instance has a unique ID (a simple global sequence number) and
26// an origin ID. When a copy is made, the new object gets a fresh ID but copies
27// the origin ID from the original. When a new Logger is created from scratch,
28// it gets a fresh ID, and the origin ID is the same as the ID (default
29// constructor) or given as an argument (explicit constructor).
30class Logger {
31 public:
kwibergb2137952016-03-17 08:38:12 -070032 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
33 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020034 Log("explicit constructor");
35 }
danilchap9e83c972016-10-18 04:07:18 -070036 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value)
37 : id_(g_next_id++), origin_(origin) {
38 Log("multi parameter constructor");
39 }
kwibergb2137952016-03-17 08:38:12 -070040 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020041 LogFrom("copy constructor", other);
42 }
kwibergb2137952016-03-17 08:38:12 -070043 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020044 LogFrom("move constructor", other);
45 }
46 ~Logger() { Log("destructor"); }
47 Logger& operator=(const Logger& other) {
48 origin_ = other.origin_;
49 LogFrom("operator= copy", other);
50 return *this;
51 }
52 Logger& operator=(Logger&& other) {
53 origin_ = other.origin_;
54 LogFrom("operator= move", other);
55 return *this;
56 }
57 friend void swap(Logger& a, Logger& b) {
58 using std::swap;
59 swap(a.origin_, b.origin_);
60 Log2("swap", a, b);
61 }
62 friend bool operator==(const Logger& a, const Logger& b) {
63 Log2("operator==", a, b);
64 return a.origin_ == b.origin_;
65 }
66 friend bool operator!=(const Logger& a, const Logger& b) {
67 Log2("operator!=", a, b);
68 return a.origin_ != b.origin_;
69 }
70 void Foo() { Log("Foo()"); }
71 void Foo() const { Log("Foo() const"); }
jbauch555604a2016-04-26 03:13:22 -070072 static std::unique_ptr<std::vector<std::string>> Setup() {
73 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -070074 g_log = s.get();
75 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +020076 return s;
77 }
78
79 private:
80 int id_;
81 int origin_;
kwibergb2137952016-03-17 08:38:12 -070082 static std::vector<std::string>* g_log;
83 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +020084 void Log(const char* msg) const {
85 std::ostringstream oss;
86 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -070087 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +020088 }
89 void LogFrom(const char* msg, const Logger& other) const {
90 std::ostringstream oss;
91 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
92 << other.origin_ << ")";
kwibergb2137952016-03-17 08:38:12 -070093 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +020094 }
95 static void Log2(const char* msg, const Logger& a, const Logger& b) {
96 std::ostringstream oss;
97 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
98 << b.origin_;
kwibergb2137952016-03-17 08:38:12 -070099 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200100 }
101};
102
kwibergb2137952016-03-17 08:38:12 -0700103std::vector<std::string>* Logger::g_log = nullptr;
104int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200105
106// Append all the other args to the vector pointed to by the first arg.
107template <typename T>
108void VectorAppend(std::vector<T>* v) {}
109template <typename T, typename... Ts>
110void VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
111 v->push_back(e);
112 VectorAppend(v, es...);
113}
114
115// Create a vector of strings. Because we're not allowed to use
116// std::initializer_list.
117template <typename... Ts>
118std::vector<std::string> V(Ts... es) {
119 std::vector<std::string> strings;
120 VectorAppend(&strings, static_cast<std::string>(es)...);
121 return strings;
122}
123
124} // namespace
125
Karl Wibergbe579832015-11-10 22:34:18 +0100126TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200127 auto log = Logger::Setup();
128 {
Karl Wibergbe579832015-11-10 22:34:18 +0100129 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200130 EXPECT_FALSE(x);
131 }
kwibergd0404802016-05-09 06:06:05 -0700132 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200133}
134
Karl Wibergbe579832015-11-10 22:34:18 +0100135TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200136 auto log = Logger::Setup();
137 {
Karl Wibergbe579832015-11-10 22:34:18 +0100138 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200139 EXPECT_FALSE(x);
140 auto y = x;
141 EXPECT_FALSE(y);
142 }
kwibergd0404802016-05-09 06:06:05 -0700143 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200144}
145
Karl Wibergbe579832015-11-10 22:34:18 +0100146TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200147 auto log = Logger::Setup();
148 {
149 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100150 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200151 EXPECT_TRUE(x);
152 log->push_back("---");
153 auto y = x;
154 EXPECT_TRUE(y);
155 log->push_back("---");
156 }
157 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
158 "---", "2:0. copy constructor (from 1:0)", "---",
159 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
160 *log);
161}
162
Karl Wibergbe579832015-11-10 22:34:18 +0100163TEST(OptionalTest, TestConstructMoveEmpty) {
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);
kwibergcea7c2f2016-01-07 05:52:04 -0800168 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200169 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, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200175 auto log = Logger::Setup();
176 {
Karl Wibergbe579832015-11-10 22:34:18 +0100177 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200178 EXPECT_TRUE(x);
179 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800180 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200181 EXPECT_TRUE(x);
182 EXPECT_TRUE(y);
183 log->push_back("---");
184 }
185 EXPECT_EQ(
186 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
187 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
188 "2:17. destructor", "1:17. destructor"),
189 *log);
190}
191
Karl Wibergbe579832015-11-10 22:34:18 +0100192TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200193 auto log = Logger::Setup();
194 {
Karl Wibergbe579832015-11-10 22:34:18 +0100195 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200196 x = y;
197 }
kwibergd0404802016-05-09 06:06:05 -0700198 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200199}
200
Karl Wibergbe579832015-11-10 22:34:18 +0100201TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200202 auto log = Logger::Setup();
203 {
Karl Wibergbe579832015-11-10 22:34:18 +0100204 Optional<Logger> x(Logger(17));
205 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200206 log->push_back("---");
207 x = y;
208 log->push_back("---");
209 }
210 EXPECT_EQ(
211 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700212 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200213 *log);
214}
215
Karl Wibergbe579832015-11-10 22:34:18 +0100216TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200217 auto log = Logger::Setup();
218 {
Karl Wibergbe579832015-11-10 22:34:18 +0100219 Optional<Logger> x;
220 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200221 log->push_back("---");
222 x = y;
223 log->push_back("---");
224 }
kwibergd0404802016-05-09 06:06:05 -0700225 EXPECT_EQ(
226 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
227 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
228 "1:17. destructor", "2:17. destructor"),
229 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200230}
231
Karl Wibergbe579832015-11-10 22:34:18 +0100232TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200233 auto log = Logger::Setup();
234 {
Karl Wibergbe579832015-11-10 22:34:18 +0100235 Optional<Logger> x(Logger(17));
236 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200237 log->push_back("---");
238 x = y;
239 log->push_back("---");
240 }
241 EXPECT_EQ(
242 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
243 "0:17. destructor", "2:42. explicit constructor",
244 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
245 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
246 "1:42. destructor"),
247 *log);
248}
249
Karl Wibergbe579832015-11-10 22:34:18 +0100250TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200251 auto log = Logger::Setup();
252 {
Karl Wibergbe579832015-11-10 22:34:18 +0100253 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200254 Logger y(17);
255 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100256 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200257 log->push_back("---");
258 }
kwibergd0404802016-05-09 06:06:05 -0700259 EXPECT_EQ(V("0:17. explicit constructor", "---",
260 "1:17. copy constructor (from 0:17)",
261 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
262 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200263 *log);
264}
265
Karl Wibergbe579832015-11-10 22:34:18 +0100266TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200267 auto log = Logger::Setup();
268 {
Karl Wibergbe579832015-11-10 22:34:18 +0100269 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200270 Logger y(42);
271 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100272 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200273 log->push_back("---");
274 }
275 EXPECT_EQ(
276 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
277 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700278 "3:42. copy constructor (from 2:42)",
279 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
280 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200281 *log);
282}
283
Karl Wibergbe579832015-11-10 22:34:18 +0100284TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200285 auto log = Logger::Setup();
286 {
Karl Wibergbe579832015-11-10 22:34:18 +0100287 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800288 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200289 }
kwibergd0404802016-05-09 06:06:05 -0700290 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200291}
292
Karl Wibergbe579832015-11-10 22:34:18 +0100293TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200294 auto log = Logger::Setup();
295 {
Karl Wibergbe579832015-11-10 22:34:18 +0100296 Optional<Logger> x(Logger(17));
297 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200298 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800299 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200300 log->push_back("---");
301 }
302 EXPECT_EQ(
303 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700304 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200305 *log);
306}
307
Karl Wibergbe579832015-11-10 22:34:18 +0100308TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200309 auto log = Logger::Setup();
310 {
Karl Wibergbe579832015-11-10 22:34:18 +0100311 Optional<Logger> x;
312 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200313 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800314 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200315 log->push_back("---");
316 }
kwibergd0404802016-05-09 06:06:05 -0700317 EXPECT_EQ(
318 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
319 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
320 "1:17. destructor", "2:17. destructor"),
321 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200322}
323
Karl Wibergbe579832015-11-10 22:34:18 +0100324TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200325 auto log = Logger::Setup();
326 {
Karl Wibergbe579832015-11-10 22:34:18 +0100327 Optional<Logger> x(Logger(17));
328 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200329 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800330 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200331 log->push_back("---");
332 }
333 EXPECT_EQ(
334 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
335 "0:17. destructor", "2:42. explicit constructor",
336 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
337 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
338 "1:42. destructor"),
339 *log);
340}
341
Karl Wibergbe579832015-11-10 22:34:18 +0100342TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200343 auto log = Logger::Setup();
344 {
Karl Wibergbe579832015-11-10 22:34:18 +0100345 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200346 Logger y(17);
347 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800348 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200349 log->push_back("---");
350 }
kwibergd0404802016-05-09 06:06:05 -0700351 EXPECT_EQ(V("0:17. explicit constructor", "---",
352 "1:17. move constructor (from 0:17)",
353 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
354 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200355 *log);
356}
357
Karl Wibergbe579832015-11-10 22:34:18 +0100358TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200359 auto log = Logger::Setup();
360 {
Karl Wibergbe579832015-11-10 22:34:18 +0100361 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200362 Logger y(42);
363 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800364 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200365 log->push_back("---");
366 }
367 EXPECT_EQ(
368 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
369 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700370 "3:42. move constructor (from 2:42)",
371 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
372 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200373 *log);
374}
375
danilchapc4fd23c2016-10-17 07:16:54 -0700376TEST(OptionalTest, TestResetEmpty) {
377 auto log = Logger::Setup();
378 {
379 Optional<Logger> x;
380 x.reset();
381 }
382 EXPECT_EQ(V(), *log);
383}
384
385TEST(OptionalTest, TestResetFull) {
386 auto log = Logger::Setup();
387 {
388 Optional<Logger> x(Logger(17));
389 log->push_back("---");
390 x.reset();
391 log->push_back("---");
392 }
393 EXPECT_EQ(
394 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
395 "0:17. destructor", "---", "1:17. destructor", "---"),
396 *log);
397}
398
danilchap9e83c972016-10-18 04:07:18 -0700399TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
400 auto log = Logger::Setup();
401 {
402 Optional<Logger> x;
403 log->push_back("---");
404 x.emplace(42);
405 log->push_back("---");
406 }
407 // clang-format off
408 EXPECT_EQ(V("---",
409 "0:42. explicit constructor",
410 "---",
411 "0:42. destructor"),
412 *log);
413 // clang-format on
414}
415
416TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
417 auto log = Logger::Setup();
418 {
419 Optional<Logger> x;
420 Logger ref(21);
421 Logger value(35);
422 log->push_back("---");
423 x.emplace(42, ref, std::move(value));
424 log->push_back("---");
425 }
426 // clang-format off
427 EXPECT_EQ(V("0:21. explicit constructor",
428 "1:35. explicit constructor",
429 "---",
430 "2:35. move constructor (from 1:35)",
431 "3:42. multi parameter constructor",
432 "2:35. destructor",
433 "---",
434 "1:35. destructor",
435 "0:21. destructor",
436 "3:42. destructor"),
437 *log);
438 // clang-format on
439}
440
441TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
442 auto log = Logger::Setup();
443 {
444 Optional<Logger> x;
445 Logger y(42);
446 log->push_back("---");
447 x.emplace(y);
448 log->push_back("---");
449 }
450 // clang-format off
451 EXPECT_EQ(V("0:42. explicit constructor",
452 "---",
453 "1:42. copy constructor (from 0:42)",
454 "---",
455 "0:42. destructor",
456 "1:42. destructor"),
457 *log);
458 // clang-format on
459}
460
461TEST(OptionalTest, TestEmplaceEmptyWithMove) {
462 auto log = Logger::Setup();
463 {
464 Optional<Logger> x;
465 Logger y(42);
466 log->push_back("---");
467 x.emplace(std::move(y));
468 log->push_back("---");
469 }
470 // clang-format off
471 EXPECT_EQ(V("0:42. explicit constructor",
472 "---",
473 "1:42. move constructor (from 0:42)",
474 "---",
475 "0:42. destructor",
476 "1:42. destructor"),
477 *log);
478 // clang-format on
479}
480
481TEST(OptionalTest, TestEmplaceFullWithExplicit) {
482 auto log = Logger::Setup();
483 {
484 Optional<Logger> x(Logger(17));
485 log->push_back("---");
486 x.emplace(42);
487 log->push_back("---");
488 }
489 // clang-format off
490 EXPECT_EQ(
491 V("0:17. explicit constructor",
492 "1:17. move constructor (from 0:17)",
493 "0:17. destructor",
494 "---",
495 "1:17. destructor",
496 "2:42. explicit constructor",
497 "---",
498 "2:42. destructor"),
499 *log);
500 // clang-format on
501}
502
503TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
504 auto log = Logger::Setup();
505 {
506 Optional<Logger> x(Logger(17));
507 Logger ref(21);
508 Logger value(35);
509 log->push_back("---");
510 x.emplace(42, ref, std::move(value));
511 log->push_back("---");
512 }
513 // clang-format off
514 EXPECT_EQ(V("0:17. explicit constructor",
515 "1:17. move constructor (from 0:17)",
516 "0:17. destructor",
517 "2:21. explicit constructor",
518 "3:35. explicit constructor",
519 "---",
520 "1:17. destructor",
521 "4:35. move constructor (from 3:35)",
522 "5:42. multi parameter constructor",
523 "4:35. destructor",
524 "---",
525 "3:35. destructor",
526 "2:21. destructor",
527 "5:42. destructor"),
528 *log);
529 // clang-format on
530}
531
532TEST(OptionalTest, TestEmplaceFullWithCopy) {
533 auto log = Logger::Setup();
534 {
535 Optional<Logger> x(Logger(17));
536 Logger y(42);
537 log->push_back("---");
538 x.emplace(y);
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:42. explicit constructor",
546 "---",
547 "1:17. destructor",
548 "3:42. copy constructor (from 2:42)",
549 "---",
550 "2:42. destructor",
551 "3:42. destructor"),
552 *log);
553 // clang-format on
554}
555
556TEST(OptionalTest, TestEmplaceFullWithMove) {
557 auto log = Logger::Setup();
558 {
559 Optional<Logger> x(Logger(17));
560 Logger y(42);
561 log->push_back("---");
562 x.emplace(std::move(y));
563 log->push_back("---");
564 }
565 // clang-format off
566 EXPECT_EQ(V("0:17. explicit constructor",
567 "1:17. move constructor (from 0:17)",
568 "0:17. destructor",
569 "2:42. explicit constructor",
570 "---",
571 "1:17. destructor",
572 "3:42. move constructor (from 2:42)",
573 "---",
574 "2:42. destructor",
575 "3:42. destructor"),
576 *log);
577 // clang-format on
578}
579
Karl Wibergbe579832015-11-10 22:34:18 +0100580TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200581 auto log = Logger::Setup();
582 {
Karl Wibergbe579832015-11-10 22:34:18 +0100583 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200584 const auto& y = x;
585 log->push_back("---");
586 x->Foo();
587 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800588 std::move(x)->Foo();
589 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200590 log->push_back("---");
591 (*x).Foo();
592 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800593 (*std::move(x)).Foo();
594 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200595 log->push_back("---");
596 }
597 EXPECT_EQ(V("0:42. explicit constructor",
598 "1:42. move constructor (from 0:42)", "0:42. destructor", "---",
599 "1:42. Foo()", "1:42. Foo() const", "1:42. Foo()",
600 "1:42. Foo() const", "---", "1:42. Foo()", "1:42. Foo() const",
601 "1:42. Foo()", "1:42. Foo() const", "---", "1:42. destructor"),
602 *log);
603}
604
Karl Wibergbe579832015-11-10 22:34:18 +0100605TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200606 auto log = Logger::Setup();
607 {
608 const Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100609 Optional<Logger> x(a);
610 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200611 log->push_back("-1-");
612 EXPECT_EQ(a, x.value_or(Logger(42)));
613 log->push_back("-2-");
614 EXPECT_EQ(b, y.value_or(Logger(42)));
615 log->push_back("-3-");
Karl Wibergbe579832015-11-10 22:34:18 +0100616 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200617 log->push_back("-4-");
Karl Wibergbe579832015-11-10 22:34:18 +0100618 EXPECT_EQ(b, Optional<Logger>().value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200619 log->push_back("-5-");
620 }
621 EXPECT_EQ(
622 V("0:17. explicit constructor", "1:42. explicit constructor",
kwibergd0404802016-05-09 06:06:05 -0700623 "2:17. copy constructor (from 0:17)", "-1-",
624 "3:42. explicit constructor", "operator== 0:17, 2:17",
625 "3:42. destructor", "-2-", "4:42. explicit constructor",
626 "operator== 1:42, 4:42", "4:42. destructor", "-3-",
627 "5:17. explicit constructor", "6:17. move constructor (from 5:17)",
628 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-",
629 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200630 "0:17. destructor"),
631 *log);
632}
633
Karl Wibergbe579832015-11-10 22:34:18 +0100634TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200635 auto log = Logger::Setup();
636 {
637 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100638 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200639 log->push_back("---");
640 EXPECT_EQ(ma1, ma1);
641 EXPECT_EQ(ma1, ma2);
642 EXPECT_NE(ma1, mb);
643 EXPECT_NE(ma1, me1);
644 EXPECT_EQ(me1, me1);
645 EXPECT_EQ(me1, me2);
646 log->push_back("---");
647 }
kwibergd0404802016-05-09 06:06:05 -0700648 EXPECT_EQ(
649 V("0:17. explicit constructor", "1:42. explicit constructor",
650 "2:17. copy constructor (from 0:17)",
651 "3:17. copy constructor (from 0:17)",
652 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
653 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
654 "4:42. destructor", "3:17. destructor", "2:17. destructor",
655 "1:42. destructor", "0:17. destructor"),
656 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200657}
658
danilchape0370602016-10-20 00:58:15 -0700659TEST(OptionalTest, TestEqualityWithObject) {
660 auto log = Logger::Setup();
661 {
662 Logger a(17), b(42);
663 Optional<Logger> ma(a), me;
664 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE
665 // macros because those operators are under test.
666 log->push_back("---");
667
668 EXPECT_TRUE(ma == a);
669 EXPECT_TRUE(a == ma);
670 EXPECT_FALSE(ma == b);
671 EXPECT_FALSE(b == ma);
672 EXPECT_FALSE(me == a);
673 EXPECT_FALSE(a == me);
674
675 EXPECT_FALSE(ma != a);
676 EXPECT_FALSE(a != ma);
677 EXPECT_TRUE(ma != b);
678 EXPECT_TRUE(b != ma);
679 EXPECT_TRUE(me != a);
680 EXPECT_TRUE(a != me);
681
682 log->push_back("---");
683 }
684 // clang-format off
685 EXPECT_EQ(V("0:17. explicit constructor",
686 "1:42. explicit constructor",
687 "2:17. copy constructor (from 0:17)",
688 "---",
689 "operator== 2:17, 0:17",
690 "operator== 0:17, 2:17",
691 "operator== 2:17, 1:42",
692 "operator== 1:42, 2:17",
693 // No operator should be called when comparing to empty.
694 "operator!= 2:17, 0:17",
695 "operator!= 0:17, 2:17",
696 "operator!= 2:17, 1:42",
697 "operator!= 1:42, 2:17",
698 // No operator should be called when comparing to empty.
699 "---",
700 "2:17. destructor",
701 "1:42. destructor",
702 "0:17. destructor"),
703 *log);
704 // clang-format on
705}
706
Karl Wibergbe579832015-11-10 22:34:18 +0100707TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200708 auto log = Logger::Setup();
709 {
710 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100711 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200712 log->push_back("---");
713 swap(x1, x2); // Swap full <-> full.
714 swap(y1, y2); // Swap full <-> empty.
715 swap(z1, z2); // Swap empty <-> empty.
716 log->push_back("---");
717 }
718 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
719 "2:17. copy constructor (from 0:17)",
720 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700721 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
722 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
723 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200724 "1:42. destructor", "0:17. destructor"),
725 *log);
726}
727
728} // namespace rtc