blob: 2149033f40486ccba5c21d21a4cd0987050eebc1 [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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "api/optional.h"
18#include "rtc_base/gunit.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
kwiberg84f6a3f2017-09-05 08:43:13 -070040std::ostream& operator<<(std::ostream& os, const MyPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080041 os << mpt.value;
42 return os;
43}
44
kwiberg84f6a3f2017-09-05 08:43:13 -070045std::ostream& operator<<(std::ostream& os, const MyOstreamPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080046 os << mpt.value;
47 return os;
48}
49
Karl Wiberg6e587202015-10-21 12:43:56 +020050// Class whose instances logs various method calls (constructor, destructor,
51// etc.). Each instance has a unique ID (a simple global sequence number) and
52// an origin ID. When a copy is made, the new object gets a fresh ID but copies
53// the origin ID from the original. When a new Logger is created from scratch,
54// it gets a fresh ID, and the origin ID is the same as the ID (default
55// constructor) or given as an argument (explicit constructor).
56class Logger {
57 public:
kwibergb2137952016-03-17 08:38:12 -070058 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
59 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020060 Log("explicit constructor");
61 }
danilchap9e83c972016-10-18 04:07:18 -070062 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value)
63 : id_(g_next_id++), origin_(origin) {
64 Log("multi parameter constructor");
65 }
kwibergb2137952016-03-17 08:38:12 -070066 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020067 LogFrom("copy constructor", other);
68 }
kwibergb2137952016-03-17 08:38:12 -070069 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020070 LogFrom("move constructor", other);
71 }
72 ~Logger() { Log("destructor"); }
73 Logger& operator=(const Logger& other) {
74 origin_ = other.origin_;
75 LogFrom("operator= copy", other);
76 return *this;
77 }
78 Logger& operator=(Logger&& other) {
79 origin_ = other.origin_;
80 LogFrom("operator= move", other);
81 return *this;
82 }
83 friend void swap(Logger& a, Logger& b) {
84 using std::swap;
85 swap(a.origin_, b.origin_);
86 Log2("swap", a, b);
87 }
88 friend bool operator==(const Logger& a, const Logger& b) {
89 Log2("operator==", a, b);
90 return a.origin_ == b.origin_;
91 }
92 friend bool operator!=(const Logger& a, const Logger& b) {
93 Log2("operator!=", a, b);
94 return a.origin_ != b.origin_;
95 }
96 void Foo() { Log("Foo()"); }
97 void Foo() const { Log("Foo() const"); }
jbauch555604a2016-04-26 03:13:22 -070098 static std::unique_ptr<std::vector<std::string>> Setup() {
99 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -0700100 g_log = s.get();
101 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200102 return s;
103 }
104
105 private:
106 int id_;
107 int origin_;
kwibergb2137952016-03-17 08:38:12 -0700108 static std::vector<std::string>* g_log;
109 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +0200110 void Log(const char* msg) const {
111 std::ostringstream oss;
112 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -0700113 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200114 }
115 void LogFrom(const char* msg, const Logger& other) const {
116 std::ostringstream oss;
117 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
118 << other.origin_ << ")";
kwibergb2137952016-03-17 08:38:12 -0700119 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200120 }
121 static void Log2(const char* msg, const Logger& a, const Logger& b) {
122 std::ostringstream oss;
123 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
124 << b.origin_;
kwibergb2137952016-03-17 08:38:12 -0700125 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200126 }
127};
128
kwibergb2137952016-03-17 08:38:12 -0700129std::vector<std::string>* Logger::g_log = nullptr;
130int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200131
132// Append all the other args to the vector pointed to by the first arg.
133template <typename T>
134void VectorAppend(std::vector<T>* v) {}
135template <typename T, typename... Ts>
136void VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
137 v->push_back(e);
138 VectorAppend(v, es...);
139}
140
141// Create a vector of strings. Because we're not allowed to use
142// std::initializer_list.
143template <typename... Ts>
144std::vector<std::string> V(Ts... es) {
145 std::vector<std::string> strings;
146 VectorAppend(&strings, static_cast<std::string>(es)...);
147 return strings;
148}
149
150} // namespace
151
Karl Wibergbe579832015-11-10 22:34:18 +0100152TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200153 auto log = Logger::Setup();
154 {
Karl Wibergbe579832015-11-10 22:34:18 +0100155 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200156 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700157 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200158 }
kwibergd0404802016-05-09 06:06:05 -0700159 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200160}
161
Oskar Sundbome4032122017-11-15 12:24:28 +0100162TEST(OptionalTest, TestConstructNullopt) {
163 auto log = Logger::Setup();
164 {
165 Optional<Logger> x(nullopt);
166 EXPECT_FALSE(x);
167 EXPECT_FALSE(x.has_value());
168 }
169 EXPECT_EQ(V(), *log);
170}
171
Karl Wibergbe579832015-11-10 22:34:18 +0100172TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200173 auto log = Logger::Setup();
174 {
Karl Wibergbe579832015-11-10 22:34:18 +0100175 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200176 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700177 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200178 auto y = x;
179 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700180 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200181 }
kwibergd0404802016-05-09 06:06:05 -0700182 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200183}
184
Karl Wibergbe579832015-11-10 22:34:18 +0100185TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200186 auto log = Logger::Setup();
187 {
188 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100189 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200190 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700191 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200192 log->push_back("---");
193 auto y = x;
194 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700195 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200196 log->push_back("---");
197 }
198 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
199 "---", "2:0. copy constructor (from 1:0)", "---",
200 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
201 *log);
202}
203
Karl Wibergbe579832015-11-10 22:34:18 +0100204TEST(OptionalTest, TestConstructMoveEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200205 auto log = Logger::Setup();
206 {
Karl Wibergbe579832015-11-10 22:34:18 +0100207 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200208 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700209 EXPECT_FALSE(x.has_value());
kwibergcea7c2f2016-01-07 05:52:04 -0800210 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200211 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700212 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200213 }
kwibergd0404802016-05-09 06:06:05 -0700214 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200215}
216
Karl Wibergbe579832015-11-10 22:34:18 +0100217TEST(OptionalTest, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200218 auto log = Logger::Setup();
219 {
Karl Wibergbe579832015-11-10 22:34:18 +0100220 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200221 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700222 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200223 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800224 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200225 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700226 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200227 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700228 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200229 log->push_back("---");
230 }
231 EXPECT_EQ(
232 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
233 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
234 "2:17. destructor", "1:17. destructor"),
235 *log);
236}
237
Karl Wibergbe579832015-11-10 22:34:18 +0100238TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200239 auto log = Logger::Setup();
240 {
Karl Wibergbe579832015-11-10 22:34:18 +0100241 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200242 x = y;
243 }
kwibergd0404802016-05-09 06:06:05 -0700244 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200245}
246
Karl Wibergbe579832015-11-10 22:34:18 +0100247TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200248 auto log = Logger::Setup();
249 {
Karl Wibergbe579832015-11-10 22:34:18 +0100250 Optional<Logger> x(Logger(17));
251 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200252 log->push_back("---");
253 x = y;
254 log->push_back("---");
255 }
256 EXPECT_EQ(
257 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700258 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200259 *log);
260}
261
Oskar Sundbome4032122017-11-15 12:24:28 +0100262TEST(OptionalTest, TestCopyAssignToFullFromNullopt) {
263 auto log = Logger::Setup();
264 {
265 Optional<Logger> x(Logger(17));
266 log->push_back("---");
267 x = nullopt;
268 log->push_back("---");
269 EXPECT_FALSE(x);
270 }
271 EXPECT_EQ(
272 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
273 "0:17. destructor", "---", "1:17. destructor", "---"),
274 *log);
275}
276
277TEST(OptionalTest, TestCopyAssignToFullFromEmptyBraces) {
278 auto log = Logger::Setup();
279 {
280 Optional<Logger> x(Logger(17));
281 log->push_back("---");
282 x = {};
283 log->push_back("---");
284 EXPECT_FALSE(x);
285 }
286 EXPECT_EQ(
287 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
288 "0:17. destructor", "---", "1:17. destructor", "---"),
289 *log);
290}
291
Karl Wibergbe579832015-11-10 22:34:18 +0100292TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200293 auto log = Logger::Setup();
294 {
Karl Wibergbe579832015-11-10 22:34:18 +0100295 Optional<Logger> x;
296 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200297 log->push_back("---");
298 x = y;
299 log->push_back("---");
300 }
kwibergd0404802016-05-09 06:06:05 -0700301 EXPECT_EQ(
302 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
303 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
304 "1:17. destructor", "2:17. destructor"),
305 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200306}
307
Karl Wibergbe579832015-11-10 22:34:18 +0100308TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200309 auto log = Logger::Setup();
310 {
Karl Wibergbe579832015-11-10 22:34:18 +0100311 Optional<Logger> x(Logger(17));
312 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200313 log->push_back("---");
314 x = y;
315 log->push_back("---");
316 }
317 EXPECT_EQ(
318 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
319 "0:17. destructor", "2:42. explicit constructor",
320 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
321 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
322 "1:42. destructor"),
323 *log);
324}
325
Karl Wibergbe579832015-11-10 22:34:18 +0100326TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200327 auto log = Logger::Setup();
328 {
Karl Wibergbe579832015-11-10 22:34:18 +0100329 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200330 Logger y(17);
331 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100332 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200333 log->push_back("---");
334 }
kwibergd0404802016-05-09 06:06:05 -0700335 EXPECT_EQ(V("0:17. explicit constructor", "---",
336 "1:17. copy constructor (from 0:17)",
337 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
338 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200339 *log);
340}
341
Karl Wibergbe579832015-11-10 22:34:18 +0100342TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200343 auto log = Logger::Setup();
344 {
Karl Wibergbe579832015-11-10 22:34:18 +0100345 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200346 Logger y(42);
347 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100348 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200349 log->push_back("---");
350 }
351 EXPECT_EQ(
352 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
353 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700354 "3:42. copy constructor (from 2:42)",
355 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
356 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200357 *log);
358}
359
Karl Wibergbe579832015-11-10 22:34:18 +0100360TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200361 auto log = Logger::Setup();
362 {
Karl Wibergbe579832015-11-10 22:34:18 +0100363 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800364 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200365 }
kwibergd0404802016-05-09 06:06:05 -0700366 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200367}
368
Karl Wibergbe579832015-11-10 22:34:18 +0100369TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200370 auto log = Logger::Setup();
371 {
Karl Wibergbe579832015-11-10 22:34:18 +0100372 Optional<Logger> x(Logger(17));
373 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200374 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800375 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200376 log->push_back("---");
377 }
378 EXPECT_EQ(
379 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700380 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200381 *log);
382}
383
Karl Wibergbe579832015-11-10 22:34:18 +0100384TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200385 auto log = Logger::Setup();
386 {
Karl Wibergbe579832015-11-10 22:34:18 +0100387 Optional<Logger> x;
388 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200389 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800390 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200391 log->push_back("---");
392 }
kwibergd0404802016-05-09 06:06:05 -0700393 EXPECT_EQ(
394 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
395 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
396 "1:17. destructor", "2:17. destructor"),
397 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200398}
399
Karl Wibergbe579832015-11-10 22:34:18 +0100400TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200401 auto log = Logger::Setup();
402 {
Karl Wibergbe579832015-11-10 22:34:18 +0100403 Optional<Logger> x(Logger(17));
404 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200405 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800406 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200407 log->push_back("---");
408 }
409 EXPECT_EQ(
410 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
411 "0:17. destructor", "2:42. explicit constructor",
412 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
413 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
414 "1:42. destructor"),
415 *log);
416}
417
Karl Wibergbe579832015-11-10 22:34:18 +0100418TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200419 auto log = Logger::Setup();
420 {
Karl Wibergbe579832015-11-10 22:34:18 +0100421 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200422 Logger y(17);
423 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800424 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200425 log->push_back("---");
426 }
kwibergd0404802016-05-09 06:06:05 -0700427 EXPECT_EQ(V("0:17. explicit constructor", "---",
428 "1:17. move constructor (from 0:17)",
429 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
430 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200431 *log);
432}
433
Karl Wibergbe579832015-11-10 22:34:18 +0100434TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200435 auto log = Logger::Setup();
436 {
Karl Wibergbe579832015-11-10 22:34:18 +0100437 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200438 Logger y(42);
439 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800440 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200441 log->push_back("---");
442 }
443 EXPECT_EQ(
444 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
445 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700446 "3:42. move constructor (from 2:42)",
447 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
448 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200449 *log);
450}
451
danilchapc4fd23c2016-10-17 07:16:54 -0700452TEST(OptionalTest, TestResetEmpty) {
453 auto log = Logger::Setup();
454 {
455 Optional<Logger> x;
456 x.reset();
457 }
458 EXPECT_EQ(V(), *log);
459}
460
461TEST(OptionalTest, TestResetFull) {
462 auto log = Logger::Setup();
463 {
464 Optional<Logger> x(Logger(17));
465 log->push_back("---");
466 x.reset();
467 log->push_back("---");
468 }
469 EXPECT_EQ(
470 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
471 "0:17. destructor", "---", "1:17. destructor", "---"),
472 *log);
473}
474
danilchap9e83c972016-10-18 04:07:18 -0700475TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
476 auto log = Logger::Setup();
477 {
478 Optional<Logger> x;
479 log->push_back("---");
480 x.emplace(42);
481 log->push_back("---");
482 }
483 // clang-format off
484 EXPECT_EQ(V("---",
485 "0:42. explicit constructor",
486 "---",
487 "0:42. destructor"),
488 *log);
489 // clang-format on
490}
491
492TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
493 auto log = Logger::Setup();
494 {
495 Optional<Logger> x;
496 Logger ref(21);
497 Logger value(35);
498 log->push_back("---");
499 x.emplace(42, ref, std::move(value));
500 log->push_back("---");
501 }
502 // clang-format off
503 EXPECT_EQ(V("0:21. explicit constructor",
504 "1:35. explicit constructor",
505 "---",
506 "2:35. move constructor (from 1:35)",
507 "3:42. multi parameter constructor",
508 "2:35. destructor",
509 "---",
510 "1:35. destructor",
511 "0:21. destructor",
512 "3:42. destructor"),
513 *log);
514 // clang-format on
515}
516
517TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
518 auto log = Logger::Setup();
519 {
520 Optional<Logger> x;
521 Logger y(42);
522 log->push_back("---");
523 x.emplace(y);
524 log->push_back("---");
525 }
526 // clang-format off
527 EXPECT_EQ(V("0:42. explicit constructor",
528 "---",
529 "1:42. copy constructor (from 0:42)",
530 "---",
531 "0:42. destructor",
532 "1:42. destructor"),
533 *log);
534 // clang-format on
535}
536
537TEST(OptionalTest, TestEmplaceEmptyWithMove) {
538 auto log = Logger::Setup();
539 {
540 Optional<Logger> x;
541 Logger y(42);
542 log->push_back("---");
543 x.emplace(std::move(y));
544 log->push_back("---");
545 }
546 // clang-format off
547 EXPECT_EQ(V("0:42. explicit constructor",
548 "---",
549 "1:42. move constructor (from 0:42)",
550 "---",
551 "0:42. destructor",
552 "1:42. destructor"),
553 *log);
554 // clang-format on
555}
556
557TEST(OptionalTest, TestEmplaceFullWithExplicit) {
558 auto log = Logger::Setup();
559 {
560 Optional<Logger> x(Logger(17));
561 log->push_back("---");
562 x.emplace(42);
563 log->push_back("---");
564 }
565 // clang-format off
566 EXPECT_EQ(
567 V("0:17. explicit constructor",
568 "1:17. move constructor (from 0:17)",
569 "0:17. destructor",
570 "---",
571 "1:17. destructor",
572 "2:42. explicit constructor",
573 "---",
574 "2:42. destructor"),
575 *log);
576 // clang-format on
577}
578
579TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
580 auto log = Logger::Setup();
581 {
582 Optional<Logger> x(Logger(17));
583 Logger ref(21);
584 Logger value(35);
585 log->push_back("---");
586 x.emplace(42, ref, std::move(value));
587 log->push_back("---");
588 }
589 // clang-format off
590 EXPECT_EQ(V("0:17. explicit constructor",
591 "1:17. move constructor (from 0:17)",
592 "0:17. destructor",
593 "2:21. explicit constructor",
594 "3:35. explicit constructor",
595 "---",
596 "1:17. destructor",
597 "4:35. move constructor (from 3:35)",
598 "5:42. multi parameter constructor",
599 "4:35. destructor",
600 "---",
601 "3:35. destructor",
602 "2:21. destructor",
603 "5:42. destructor"),
604 *log);
605 // clang-format on
606}
607
608TEST(OptionalTest, TestEmplaceFullWithCopy) {
609 auto log = Logger::Setup();
610 {
611 Optional<Logger> x(Logger(17));
612 Logger y(42);
613 log->push_back("---");
614 x.emplace(y);
615 log->push_back("---");
616 }
617 // clang-format off
618 EXPECT_EQ(V("0:17. explicit constructor",
619 "1:17. move constructor (from 0:17)",
620 "0:17. destructor",
621 "2:42. explicit constructor",
622 "---",
623 "1:17. destructor",
624 "3:42. copy constructor (from 2:42)",
625 "---",
626 "2:42. destructor",
627 "3:42. destructor"),
628 *log);
629 // clang-format on
630}
631
632TEST(OptionalTest, TestEmplaceFullWithMove) {
633 auto log = Logger::Setup();
634 {
635 Optional<Logger> x(Logger(17));
636 Logger y(42);
637 log->push_back("---");
638 x.emplace(std::move(y));
639 log->push_back("---");
640 }
641 // clang-format off
642 EXPECT_EQ(V("0:17. explicit constructor",
643 "1:17. move constructor (from 0:17)",
644 "0:17. destructor",
645 "2:42. explicit constructor",
646 "---",
647 "1:17. destructor",
648 "3:42. move constructor (from 2:42)",
649 "---",
650 "2:42. destructor",
651 "3:42. destructor"),
652 *log);
653 // clang-format on
654}
655
Karl Wibergbe579832015-11-10 22:34:18 +0100656TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200657 auto log = Logger::Setup();
658 {
Karl Wibergbe579832015-11-10 22:34:18 +0100659 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200660 const auto& y = x;
661 log->push_back("---");
662 x->Foo();
663 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800664 std::move(x)->Foo();
665 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200666 log->push_back("---");
667 (*x).Foo();
668 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800669 (*std::move(x)).Foo();
670 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200671 log->push_back("---");
tereliusf79dbad2017-06-16 06:48:13 -0700672 x.value().Foo();
673 y.value().Foo();
674 std::move(x).value().Foo();
675 std::move(y).value().Foo();
676 log->push_back("---");
Karl Wiberg6e587202015-10-21 12:43:56 +0200677 }
tereliusf79dbad2017-06-16 06:48:13 -0700678 // clang-format off
Karl Wiberg6e587202015-10-21 12:43:56 +0200679 EXPECT_EQ(V("0:42. explicit constructor",
tereliusf79dbad2017-06-16 06:48:13 -0700680 "1:42. move constructor (from 0:42)",
681 "0:42. destructor",
682 "---",
683 "1:42. Foo()",
684 "1:42. Foo() const",
685 "1:42. Foo()",
686 "1:42. Foo() const",
687 "---",
688 "1:42. Foo()",
689 "1:42. Foo() const",
690 "1:42. Foo()",
691 "1:42. Foo() const",
692 "---",
693 "1:42. Foo()",
694 "1:42. Foo() const",
695 "1:42. Foo()",
696 "1:42. Foo() const",
697 "---",
698 "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200699 *log);
tereliusf79dbad2017-06-16 06:48:13 -0700700 // clang-format on
Karl Wiberg6e587202015-10-21 12:43:56 +0200701}
702
Karl Wibergbe579832015-11-10 22:34:18 +0100703TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200704 auto log = Logger::Setup();
705 {
706 const Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100707 Optional<Logger> x(a);
708 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200709 log->push_back("-1-");
710 EXPECT_EQ(a, x.value_or(Logger(42)));
711 log->push_back("-2-");
712 EXPECT_EQ(b, y.value_or(Logger(42)));
713 log->push_back("-3-");
Karl Wibergbe579832015-11-10 22:34:18 +0100714 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200715 log->push_back("-4-");
Karl Wibergbe579832015-11-10 22:34:18 +0100716 EXPECT_EQ(b, Optional<Logger>().value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200717 log->push_back("-5-");
718 }
719 EXPECT_EQ(
720 V("0:17. explicit constructor", "1:42. explicit constructor",
kwibergd0404802016-05-09 06:06:05 -0700721 "2:17. copy constructor (from 0:17)", "-1-",
722 "3:42. explicit constructor", "operator== 0:17, 2:17",
723 "3:42. destructor", "-2-", "4:42. explicit constructor",
724 "operator== 1:42, 4:42", "4:42. destructor", "-3-",
725 "5:17. explicit constructor", "6:17. move constructor (from 5:17)",
726 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-",
727 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200728 "0:17. destructor"),
729 *log);
730}
731
Karl Wibergbe579832015-11-10 22:34:18 +0100732TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200733 auto log = Logger::Setup();
734 {
735 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100736 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200737 log->push_back("---");
738 EXPECT_EQ(ma1, ma1);
739 EXPECT_EQ(ma1, ma2);
740 EXPECT_NE(ma1, mb);
741 EXPECT_NE(ma1, me1);
742 EXPECT_EQ(me1, me1);
743 EXPECT_EQ(me1, me2);
744 log->push_back("---");
745 }
kwibergd0404802016-05-09 06:06:05 -0700746 EXPECT_EQ(
747 V("0:17. explicit constructor", "1:42. explicit constructor",
748 "2:17. copy constructor (from 0:17)",
749 "3:17. copy constructor (from 0:17)",
750 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
751 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
752 "4:42. destructor", "3:17. destructor", "2:17. destructor",
753 "1:42. destructor", "0:17. destructor"),
754 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200755}
756
Oskar Sundbome4032122017-11-15 12:24:28 +0100757TEST(OptionalTest, TestEqualityWithNullopt) {
758 auto log = Logger::Setup();
759 {
760 Logger a(17);
761 Optional<Logger> ma(a), me;
762 // Using operator== and operator!= explicitly instead of EXPECT_EQ/EXPECT_NE
763 // macros because those operators are under test.
764 log->push_back("---");
765
766 EXPECT_FALSE(ma == nullopt);
767 EXPECT_FALSE(nullopt == ma);
768 EXPECT_TRUE(me == nullopt);
769 EXPECT_TRUE(nullopt == me);
770
771 EXPECT_TRUE(ma != nullopt);
772 EXPECT_TRUE(nullopt != ma);
773 EXPECT_FALSE(me != nullopt);
774 EXPECT_FALSE(nullopt != me);
775
776 log->push_back("---");
777 }
778 // clang-format off
779 EXPECT_EQ(V("0:17. explicit constructor",
780 "1:17. copy constructor (from 0:17)",
781 "---",
782 // No operators should be called when comparing to empty.
783 "---",
784 "1:17. destructor",
785 "0:17. destructor"),
786 *log);
787 // clang-format on
788}
789
danilchape0370602016-10-20 00:58:15 -0700790TEST(OptionalTest, TestEqualityWithObject) {
791 auto log = Logger::Setup();
792 {
793 Logger a(17), b(42);
794 Optional<Logger> ma(a), me;
Oskar Sundbome4032122017-11-15 12:24:28 +0100795 // Using operator== and operator!= explicitly instead of EXPECT_EQ/EXPECT_NE
danilchape0370602016-10-20 00:58:15 -0700796 // macros because those operators are under test.
797 log->push_back("---");
798
799 EXPECT_TRUE(ma == a);
800 EXPECT_TRUE(a == ma);
801 EXPECT_FALSE(ma == b);
802 EXPECT_FALSE(b == ma);
803 EXPECT_FALSE(me == a);
804 EXPECT_FALSE(a == me);
805
806 EXPECT_FALSE(ma != a);
807 EXPECT_FALSE(a != ma);
808 EXPECT_TRUE(ma != b);
809 EXPECT_TRUE(b != ma);
810 EXPECT_TRUE(me != a);
811 EXPECT_TRUE(a != me);
812
813 log->push_back("---");
814 }
815 // clang-format off
816 EXPECT_EQ(V("0:17. explicit constructor",
817 "1:42. explicit constructor",
818 "2:17. copy constructor (from 0:17)",
819 "---",
820 "operator== 2:17, 0:17",
821 "operator== 0:17, 2:17",
822 "operator== 2:17, 1:42",
823 "operator== 1:42, 2:17",
824 // No operator should be called when comparing to empty.
825 "operator!= 2:17, 0:17",
826 "operator!= 0:17, 2:17",
827 "operator!= 2:17, 1:42",
828 "operator!= 1:42, 2:17",
829 // No operator should be called when comparing to empty.
830 "---",
831 "2:17. destructor",
832 "1:42. destructor",
833 "0:17. destructor"),
834 *log);
835 // clang-format on
836}
837
Karl Wibergbe579832015-11-10 22:34:18 +0100838TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200839 auto log = Logger::Setup();
840 {
841 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100842 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200843 log->push_back("---");
844 swap(x1, x2); // Swap full <-> full.
845 swap(y1, y2); // Swap full <-> empty.
846 swap(z1, z2); // Swap empty <-> empty.
847 log->push_back("---");
848 }
849 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
850 "2:17. copy constructor (from 0:17)",
851 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700852 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
853 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
854 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200855 "1:42. destructor", "0:17. destructor"),
856 *log);
857}
858
deadbeef81baed32017-02-10 18:11:11 -0800859TEST(OptionalTest, TestMoveValue) {
860 auto log = Logger::Setup();
861 {
862 Optional<Logger> x(Logger(42));
863 log->push_back("---");
864 Logger moved = x.MoveValue();
865 log->push_back("---");
866 }
867 EXPECT_EQ(
868 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)",
869 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---",
870 "2:42. destructor", "1:42. destructor"),
871 *log);
872}
873
ossue5c27a52017-02-20 04:41:42 -0800874TEST(OptionalTest, TestPrintTo) {
875 constexpr char kEmptyOptionalMessage[] = "<empty optional>";
876 const Optional<MyUnprintableType> empty_unprintable;
877 const Optional<MyPrintableType> empty_printable;
878 const Optional<MyOstreamPrintableType> empty_ostream_printable;
879 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable));
880 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable));
881 EXPECT_EQ(kEmptyOptionalMessage,
882 ::testing::PrintToString(empty_ostream_printable));
883 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1})));
884 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1})));
885 EXPECT_EQ("The value is 1",
886 ::testing::PrintToString(Optional<MyPrintableType>({1})));
887 EXPECT_EQ("1",
888 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1})));
889}
890
891void UnusedFunctionWorkaround() {
892 // These are here to ensure we don't get warnings about ostream and PrintTo
893 // for MyPrintableType never getting called.
894 const MyPrintableType dont_warn{17};
895 const MyOstreamPrintableType dont_warn2{18};
896 std::stringstream sstr;
897 sstr << dont_warn;
898 PrintTo(dont_warn, &sstr);
899 sstr << dont_warn2;
900}
901
Karl Wiberg6e587202015-10-21 12:43:56 +0200902} // namespace rtc