blob: f56dc6d7aceed760863b1d96a27b0de161fcea62 [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
Danil Chapovalov9dce71b2018-06-11 07:48:31 +000011// TODO(bugs.webrtc.org/8821): Delete this file when absl unittests run on
12// webrtc bots.
13
jbauch555604a2016-04-26 03:13:22 -070014#include <memory>
Karl Wiberg6e587202015-10-21 12:43:56 +020015#include <sstream>
16#include <string>
17#include <utility>
18#include <vector>
19
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "api/optional.h"
21#include "rtc_base/gunit.h"
Karl Wiberg6e587202015-10-21 12:43:56 +020022
23namespace rtc {
24
25namespace {
26
ossue5c27a52017-02-20 04:41:42 -080027struct MyUnprintableType {
28 int value;
29};
30
31struct MyPrintableType {
32 int value;
33};
34
35struct MyOstreamPrintableType {
36 int value;
37};
38
39void PrintTo(const MyPrintableType& mpt, std::ostream* os) {
40 *os << "The value is " << mpt.value;
41}
42
kwiberg84f6a3f2017-09-05 08:43:13 -070043std::ostream& operator<<(std::ostream& os, const MyPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080044 os << mpt.value;
45 return os;
46}
47
kwiberg84f6a3f2017-09-05 08:43:13 -070048std::ostream& operator<<(std::ostream& os, const MyOstreamPrintableType& mpt) {
ossue5c27a52017-02-20 04:41:42 -080049 os << mpt.value;
50 return os;
51}
52
Karl Wiberg6e587202015-10-21 12:43:56 +020053// Class whose instances logs various method calls (constructor, destructor,
54// etc.). Each instance has a unique ID (a simple global sequence number) and
55// an origin ID. When a copy is made, the new object gets a fresh ID but copies
56// the origin ID from the original. When a new Logger is created from scratch,
57// it gets a fresh ID, and the origin ID is the same as the ID (default
58// constructor) or given as an argument (explicit constructor).
59class Logger {
60 public:
kwibergb2137952016-03-17 08:38:12 -070061 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
62 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020063 Log("explicit constructor");
64 }
danilchap9e83c972016-10-18 04:07:18 -070065 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value)
66 : id_(g_next_id++), origin_(origin) {
67 Log("multi parameter constructor");
68 }
kwibergb2137952016-03-17 08:38:12 -070069 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020070 LogFrom("copy constructor", other);
71 }
kwibergb2137952016-03-17 08:38:12 -070072 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020073 LogFrom("move constructor", other);
74 }
75 ~Logger() { Log("destructor"); }
76 Logger& operator=(const Logger& other) {
77 origin_ = other.origin_;
78 LogFrom("operator= copy", other);
79 return *this;
80 }
81 Logger& operator=(Logger&& other) {
82 origin_ = other.origin_;
83 LogFrom("operator= move", other);
84 return *this;
85 }
86 friend void swap(Logger& a, Logger& b) {
87 using std::swap;
88 swap(a.origin_, b.origin_);
89 Log2("swap", a, b);
90 }
91 friend bool operator==(const Logger& a, const Logger& b) {
92 Log2("operator==", a, b);
93 return a.origin_ == b.origin_;
94 }
95 friend bool operator!=(const Logger& a, const Logger& b) {
96 Log2("operator!=", a, b);
97 return a.origin_ != b.origin_;
98 }
99 void Foo() { Log("Foo()"); }
100 void Foo() const { Log("Foo() const"); }
jbauch555604a2016-04-26 03:13:22 -0700101 static std::unique_ptr<std::vector<std::string>> Setup() {
102 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -0700103 g_log = s.get();
104 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200105 return s;
106 }
107
108 private:
109 int id_;
110 int origin_;
kwibergb2137952016-03-17 08:38:12 -0700111 static std::vector<std::string>* g_log;
112 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +0200113 void Log(const char* msg) const {
114 std::ostringstream oss;
115 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -0700116 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200117 }
118 void LogFrom(const char* msg, const Logger& other) const {
119 std::ostringstream oss;
120 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
121 << other.origin_ << ")";
kwibergb2137952016-03-17 08:38:12 -0700122 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200123 }
124 static void Log2(const char* msg, const Logger& a, const Logger& b) {
125 std::ostringstream oss;
126 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
127 << b.origin_;
kwibergb2137952016-03-17 08:38:12 -0700128 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200129 }
130};
131
kwibergb2137952016-03-17 08:38:12 -0700132std::vector<std::string>* Logger::g_log = nullptr;
133int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200134
135// Append all the other args to the vector pointed to by the first arg.
136template <typename T>
137void VectorAppend(std::vector<T>* v) {}
138template <typename T, typename... Ts>
139void VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
140 v->push_back(e);
141 VectorAppend(v, es...);
142}
143
144// Create a vector of strings. Because we're not allowed to use
145// std::initializer_list.
146template <typename... Ts>
147std::vector<std::string> V(Ts... es) {
148 std::vector<std::string> strings;
149 VectorAppend(&strings, static_cast<std::string>(es)...);
150 return strings;
151}
152
153} // namespace
154
Karl Wibergbe579832015-11-10 22:34:18 +0100155TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200156 auto log = Logger::Setup();
157 {
Karl Wibergbe579832015-11-10 22:34:18 +0100158 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200159 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700160 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200161 }
kwibergd0404802016-05-09 06:06:05 -0700162 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200163}
164
Oskar Sundbome4032122017-11-15 12:24:28 +0100165TEST(OptionalTest, TestConstructNullopt) {
166 auto log = Logger::Setup();
167 {
168 Optional<Logger> x(nullopt);
169 EXPECT_FALSE(x);
170 EXPECT_FALSE(x.has_value());
171 }
172 EXPECT_EQ(V(), *log);
173}
174
Karl Wibergbe579832015-11-10 22:34:18 +0100175TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200176 auto log = Logger::Setup();
177 {
Karl Wibergbe579832015-11-10 22:34:18 +0100178 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200179 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700180 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200181 auto y = x;
182 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700183 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200184 }
kwibergd0404802016-05-09 06:06:05 -0700185 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200186}
187
Karl Wibergbe579832015-11-10 22:34:18 +0100188TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200189 auto log = Logger::Setup();
190 {
191 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100192 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200193 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700194 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200195 log->push_back("---");
196 auto y = x;
197 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700198 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200199 log->push_back("---");
200 }
201 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
202 "---", "2:0. copy constructor (from 1:0)", "---",
203 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
204 *log);
205}
206
Karl Wibergbe579832015-11-10 22:34:18 +0100207TEST(OptionalTest, TestConstructMoveEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200208 auto log = Logger::Setup();
209 {
Karl Wibergbe579832015-11-10 22:34:18 +0100210 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200211 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700212 EXPECT_FALSE(x.has_value());
kwibergcea7c2f2016-01-07 05:52:04 -0800213 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200214 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700215 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200216 }
kwibergd0404802016-05-09 06:06:05 -0700217 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200218}
219
Karl Wibergbe579832015-11-10 22:34:18 +0100220TEST(OptionalTest, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200221 auto log = Logger::Setup();
222 {
Karl Wibergbe579832015-11-10 22:34:18 +0100223 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200224 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700225 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200226 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800227 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200228 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700229 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200230 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700231 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200232 log->push_back("---");
233 }
234 EXPECT_EQ(
235 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
236 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
237 "2:17. destructor", "1:17. destructor"),
238 *log);
239}
240
Karl Wibergbe579832015-11-10 22:34:18 +0100241TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200242 auto log = Logger::Setup();
243 {
Karl Wibergbe579832015-11-10 22:34:18 +0100244 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200245 x = y;
246 }
kwibergd0404802016-05-09 06:06:05 -0700247 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200248}
249
Karl Wibergbe579832015-11-10 22:34:18 +0100250TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200251 auto log = Logger::Setup();
252 {
Karl Wibergbe579832015-11-10 22:34:18 +0100253 Optional<Logger> x(Logger(17));
254 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200255 log->push_back("---");
256 x = y;
257 log->push_back("---");
258 }
259 EXPECT_EQ(
260 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700261 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200262 *log);
263}
264
Oskar Sundbome4032122017-11-15 12:24:28 +0100265TEST(OptionalTest, TestCopyAssignToFullFromNullopt) {
266 auto log = Logger::Setup();
267 {
268 Optional<Logger> x(Logger(17));
269 log->push_back("---");
270 x = nullopt;
271 log->push_back("---");
272 EXPECT_FALSE(x);
273 }
274 EXPECT_EQ(
275 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
276 "0:17. destructor", "---", "1:17. destructor", "---"),
277 *log);
278}
279
280TEST(OptionalTest, TestCopyAssignToFullFromEmptyBraces) {
281 auto log = Logger::Setup();
282 {
283 Optional<Logger> x(Logger(17));
284 log->push_back("---");
285 x = {};
286 log->push_back("---");
287 EXPECT_FALSE(x);
288 }
289 EXPECT_EQ(
290 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
291 "0:17. destructor", "---", "1:17. destructor", "---"),
292 *log);
293}
294
Karl Wibergbe579832015-11-10 22:34:18 +0100295TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200296 auto log = Logger::Setup();
297 {
Karl Wibergbe579832015-11-10 22:34:18 +0100298 Optional<Logger> x;
299 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200300 log->push_back("---");
301 x = y;
302 log->push_back("---");
303 }
kwibergd0404802016-05-09 06:06:05 -0700304 EXPECT_EQ(
305 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
306 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
307 "1:17. destructor", "2:17. destructor"),
308 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200309}
310
Karl Wibergbe579832015-11-10 22:34:18 +0100311TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200312 auto log = Logger::Setup();
313 {
Karl Wibergbe579832015-11-10 22:34:18 +0100314 Optional<Logger> x(Logger(17));
315 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200316 log->push_back("---");
317 x = y;
318 log->push_back("---");
319 }
320 EXPECT_EQ(
321 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
322 "0:17. destructor", "2:42. explicit constructor",
323 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
324 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
325 "1:42. destructor"),
326 *log);
327}
328
Karl Wibergbe579832015-11-10 22:34:18 +0100329TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200330 auto log = Logger::Setup();
331 {
Karl Wibergbe579832015-11-10 22:34:18 +0100332 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200333 Logger y(17);
334 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100335 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200336 log->push_back("---");
337 }
kwibergd0404802016-05-09 06:06:05 -0700338 EXPECT_EQ(V("0:17. explicit constructor", "---",
339 "1:17. copy constructor (from 0:17)",
340 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
341 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200342 *log);
343}
344
Karl Wibergbe579832015-11-10 22:34:18 +0100345TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200346 auto log = Logger::Setup();
347 {
Karl Wibergbe579832015-11-10 22:34:18 +0100348 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200349 Logger y(42);
350 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100351 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200352 log->push_back("---");
353 }
354 EXPECT_EQ(
355 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
356 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700357 "3:42. copy constructor (from 2:42)",
358 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
359 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200360 *log);
361}
362
Karl Wibergbe579832015-11-10 22:34:18 +0100363TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200364 auto log = Logger::Setup();
365 {
Karl Wibergbe579832015-11-10 22:34:18 +0100366 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800367 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200368 }
kwibergd0404802016-05-09 06:06:05 -0700369 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200370}
371
Karl Wibergbe579832015-11-10 22:34:18 +0100372TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200373 auto log = Logger::Setup();
374 {
Karl Wibergbe579832015-11-10 22:34:18 +0100375 Optional<Logger> x(Logger(17));
376 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200377 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800378 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200379 log->push_back("---");
380 }
381 EXPECT_EQ(
382 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700383 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200384 *log);
385}
386
Karl Wibergbe579832015-11-10 22:34:18 +0100387TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200388 auto log = Logger::Setup();
389 {
Karl Wibergbe579832015-11-10 22:34:18 +0100390 Optional<Logger> x;
391 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200392 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800393 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200394 log->push_back("---");
395 }
kwibergd0404802016-05-09 06:06:05 -0700396 EXPECT_EQ(
397 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
398 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
399 "1:17. destructor", "2:17. destructor"),
400 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200401}
402
Karl Wibergbe579832015-11-10 22:34:18 +0100403TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200404 auto log = Logger::Setup();
405 {
Karl Wibergbe579832015-11-10 22:34:18 +0100406 Optional<Logger> x(Logger(17));
407 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200408 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800409 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200410 log->push_back("---");
411 }
412 EXPECT_EQ(
413 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
414 "0:17. destructor", "2:42. explicit constructor",
415 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
416 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
417 "1:42. destructor"),
418 *log);
419}
420
Karl Wibergbe579832015-11-10 22:34:18 +0100421TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200422 auto log = Logger::Setup();
423 {
Karl Wibergbe579832015-11-10 22:34:18 +0100424 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200425 Logger y(17);
426 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800427 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200428 log->push_back("---");
429 }
kwibergd0404802016-05-09 06:06:05 -0700430 EXPECT_EQ(V("0:17. explicit constructor", "---",
431 "1:17. move constructor (from 0:17)",
432 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
433 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200434 *log);
435}
436
Karl Wibergbe579832015-11-10 22:34:18 +0100437TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200438 auto log = Logger::Setup();
439 {
Karl Wibergbe579832015-11-10 22:34:18 +0100440 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200441 Logger y(42);
442 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800443 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200444 log->push_back("---");
445 }
446 EXPECT_EQ(
447 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
448 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700449 "3:42. move constructor (from 2:42)",
450 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
451 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200452 *log);
453}
454
danilchapc4fd23c2016-10-17 07:16:54 -0700455TEST(OptionalTest, TestResetEmpty) {
456 auto log = Logger::Setup();
457 {
458 Optional<Logger> x;
459 x.reset();
460 }
461 EXPECT_EQ(V(), *log);
462}
463
464TEST(OptionalTest, TestResetFull) {
465 auto log = Logger::Setup();
466 {
467 Optional<Logger> x(Logger(17));
468 log->push_back("---");
469 x.reset();
470 log->push_back("---");
471 }
472 EXPECT_EQ(
473 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
474 "0:17. destructor", "---", "1:17. destructor", "---"),
475 *log);
476}
477
danilchap9e83c972016-10-18 04:07:18 -0700478TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
479 auto log = Logger::Setup();
480 {
481 Optional<Logger> x;
482 log->push_back("---");
483 x.emplace(42);
484 log->push_back("---");
485 }
486 // clang-format off
487 EXPECT_EQ(V("---",
488 "0:42. explicit constructor",
489 "---",
490 "0:42. destructor"),
491 *log);
492 // clang-format on
493}
494
495TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
496 auto log = Logger::Setup();
497 {
498 Optional<Logger> x;
499 Logger ref(21);
500 Logger value(35);
501 log->push_back("---");
502 x.emplace(42, ref, std::move(value));
503 log->push_back("---");
504 }
505 // clang-format off
506 EXPECT_EQ(V("0:21. explicit constructor",
507 "1:35. explicit constructor",
508 "---",
509 "2:35. move constructor (from 1:35)",
510 "3:42. multi parameter constructor",
511 "2:35. destructor",
512 "---",
513 "1:35. destructor",
514 "0:21. destructor",
515 "3:42. destructor"),
516 *log);
517 // clang-format on
518}
519
520TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
521 auto log = Logger::Setup();
522 {
523 Optional<Logger> x;
524 Logger y(42);
525 log->push_back("---");
526 x.emplace(y);
527 log->push_back("---");
528 }
529 // clang-format off
530 EXPECT_EQ(V("0:42. explicit constructor",
531 "---",
532 "1:42. copy constructor (from 0:42)",
533 "---",
534 "0:42. destructor",
535 "1:42. destructor"),
536 *log);
537 // clang-format on
538}
539
540TEST(OptionalTest, TestEmplaceEmptyWithMove) {
541 auto log = Logger::Setup();
542 {
543 Optional<Logger> x;
544 Logger y(42);
545 log->push_back("---");
546 x.emplace(std::move(y));
547 log->push_back("---");
548 }
549 // clang-format off
550 EXPECT_EQ(V("0:42. explicit constructor",
551 "---",
552 "1:42. move constructor (from 0:42)",
553 "---",
554 "0:42. destructor",
555 "1:42. destructor"),
556 *log);
557 // clang-format on
558}
559
560TEST(OptionalTest, TestEmplaceFullWithExplicit) {
561 auto log = Logger::Setup();
562 {
563 Optional<Logger> x(Logger(17));
564 log->push_back("---");
565 x.emplace(42);
566 log->push_back("---");
567 }
568 // clang-format off
569 EXPECT_EQ(
570 V("0:17. explicit constructor",
571 "1:17. move constructor (from 0:17)",
572 "0:17. destructor",
573 "---",
574 "1:17. destructor",
575 "2:42. explicit constructor",
576 "---",
577 "2:42. destructor"),
578 *log);
579 // clang-format on
580}
581
582TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
583 auto log = Logger::Setup();
584 {
585 Optional<Logger> x(Logger(17));
586 Logger ref(21);
587 Logger value(35);
588 log->push_back("---");
589 x.emplace(42, ref, std::move(value));
590 log->push_back("---");
591 }
592 // clang-format off
593 EXPECT_EQ(V("0:17. explicit constructor",
594 "1:17. move constructor (from 0:17)",
595 "0:17. destructor",
596 "2:21. explicit constructor",
597 "3:35. explicit constructor",
598 "---",
599 "1:17. destructor",
600 "4:35. move constructor (from 3:35)",
601 "5:42. multi parameter constructor",
602 "4:35. destructor",
603 "---",
604 "3:35. destructor",
605 "2:21. destructor",
606 "5:42. destructor"),
607 *log);
608 // clang-format on
609}
610
611TEST(OptionalTest, TestEmplaceFullWithCopy) {
612 auto log = Logger::Setup();
613 {
614 Optional<Logger> x(Logger(17));
615 Logger y(42);
616 log->push_back("---");
617 x.emplace(y);
618 log->push_back("---");
619 }
620 // clang-format off
621 EXPECT_EQ(V("0:17. explicit constructor",
622 "1:17. move constructor (from 0:17)",
623 "0:17. destructor",
624 "2:42. explicit constructor",
625 "---",
626 "1:17. destructor",
627 "3:42. copy constructor (from 2:42)",
628 "---",
629 "2:42. destructor",
630 "3:42. destructor"),
631 *log);
632 // clang-format on
633}
634
635TEST(OptionalTest, TestEmplaceFullWithMove) {
636 auto log = Logger::Setup();
637 {
638 Optional<Logger> x(Logger(17));
639 Logger y(42);
640 log->push_back("---");
641 x.emplace(std::move(y));
642 log->push_back("---");
643 }
644 // clang-format off
645 EXPECT_EQ(V("0:17. explicit constructor",
646 "1:17. move constructor (from 0:17)",
647 "0:17. destructor",
648 "2:42. explicit constructor",
649 "---",
650 "1:17. destructor",
651 "3:42. move constructor (from 2:42)",
652 "---",
653 "2:42. destructor",
654 "3:42. destructor"),
655 *log);
656 // clang-format on
657}
658
Karl Wibergbe579832015-11-10 22:34:18 +0100659TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200660 auto log = Logger::Setup();
661 {
Karl Wibergbe579832015-11-10 22:34:18 +0100662 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200663 const auto& y = x;
664 log->push_back("---");
665 x->Foo();
666 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800667 std::move(x)->Foo();
668 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200669 log->push_back("---");
670 (*x).Foo();
671 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800672 (*std::move(x)).Foo();
673 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200674 log->push_back("---");
tereliusf79dbad2017-06-16 06:48:13 -0700675 x.value().Foo();
676 y.value().Foo();
677 std::move(x).value().Foo();
678 std::move(y).value().Foo();
679 log->push_back("---");
Karl Wiberg6e587202015-10-21 12:43:56 +0200680 }
tereliusf79dbad2017-06-16 06:48:13 -0700681 // clang-format off
Karl Wiberg6e587202015-10-21 12:43:56 +0200682 EXPECT_EQ(V("0:42. explicit constructor",
tereliusf79dbad2017-06-16 06:48:13 -0700683 "1:42. move constructor (from 0:42)",
684 "0:42. destructor",
685 "---",
686 "1:42. Foo()",
687 "1:42. Foo() const",
688 "1:42. Foo()",
689 "1:42. Foo() const",
690 "---",
691 "1:42. Foo()",
692 "1:42. Foo() const",
693 "1:42. Foo()",
694 "1:42. Foo() const",
695 "---",
696 "1:42. Foo()",
697 "1:42. Foo() const",
698 "1:42. Foo()",
699 "1:42. Foo() const",
700 "---",
701 "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200702 *log);
tereliusf79dbad2017-06-16 06:48:13 -0700703 // clang-format on
Karl Wiberg6e587202015-10-21 12:43:56 +0200704}
705
Karl Wibergbe579832015-11-10 22:34:18 +0100706TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200707 auto log = Logger::Setup();
Danil Chapovalov9dce71b2018-06-11 07:48:31 +0000708 const Logger a(17), b(42);
709 Optional<Logger> x(a);
710 Optional<Logger> y;
711 EXPECT_EQ(a, x.value_or(Logger(42)));
712 EXPECT_EQ(b, y.value_or(Logger(42)));
713 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
714 EXPECT_EQ(b, Optional<Logger>().value_or(b));
715 // Can't expect exact list of constructors and destructors because it is
716 // compiler-dependent. i.e. msvc produce different output than clang. Calls
717 // above are subject to copy elision that allow to change behavior.
Karl Wiberg6e587202015-10-21 12:43:56 +0200718}
719
Karl Wibergbe579832015-11-10 22:34:18 +0100720TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200721 auto log = Logger::Setup();
722 {
723 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100724 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200725 log->push_back("---");
726 EXPECT_EQ(ma1, ma1);
727 EXPECT_EQ(ma1, ma2);
728 EXPECT_NE(ma1, mb);
729 EXPECT_NE(ma1, me1);
730 EXPECT_EQ(me1, me1);
731 EXPECT_EQ(me1, me2);
732 log->push_back("---");
733 }
kwibergd0404802016-05-09 06:06:05 -0700734 EXPECT_EQ(
735 V("0:17. explicit constructor", "1:42. explicit constructor",
736 "2:17. copy constructor (from 0:17)",
737 "3:17. copy constructor (from 0:17)",
738 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
739 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
740 "4:42. destructor", "3:17. destructor", "2:17. destructor",
741 "1:42. destructor", "0:17. destructor"),
742 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200743}
744
Oskar Sundbome4032122017-11-15 12:24:28 +0100745TEST(OptionalTest, TestEqualityWithNullopt) {
746 auto log = Logger::Setup();
747 {
748 Logger a(17);
749 Optional<Logger> ma(a), me;
750 // Using operator== and operator!= explicitly instead of EXPECT_EQ/EXPECT_NE
751 // macros because those operators are under test.
752 log->push_back("---");
753
754 EXPECT_FALSE(ma == nullopt);
755 EXPECT_FALSE(nullopt == ma);
756 EXPECT_TRUE(me == nullopt);
757 EXPECT_TRUE(nullopt == me);
758
759 EXPECT_TRUE(ma != nullopt);
760 EXPECT_TRUE(nullopt != ma);
761 EXPECT_FALSE(me != nullopt);
762 EXPECT_FALSE(nullopt != me);
763
764 log->push_back("---");
765 }
766 // clang-format off
767 EXPECT_EQ(V("0:17. explicit constructor",
768 "1:17. copy constructor (from 0:17)",
769 "---",
770 // No operators should be called when comparing to empty.
771 "---",
772 "1:17. destructor",
773 "0:17. destructor"),
774 *log);
775 // clang-format on
776}
777
danilchape0370602016-10-20 00:58:15 -0700778TEST(OptionalTest, TestEqualityWithObject) {
779 auto log = Logger::Setup();
780 {
781 Logger a(17), b(42);
782 Optional<Logger> ma(a), me;
Oskar Sundbome4032122017-11-15 12:24:28 +0100783 // Using operator== and operator!= explicitly instead of EXPECT_EQ/EXPECT_NE
danilchape0370602016-10-20 00:58:15 -0700784 // macros because those operators are under test.
785 log->push_back("---");
786
787 EXPECT_TRUE(ma == a);
788 EXPECT_TRUE(a == ma);
789 EXPECT_FALSE(ma == b);
790 EXPECT_FALSE(b == ma);
791 EXPECT_FALSE(me == a);
792 EXPECT_FALSE(a == me);
793
794 EXPECT_FALSE(ma != a);
795 EXPECT_FALSE(a != ma);
796 EXPECT_TRUE(ma != b);
797 EXPECT_TRUE(b != ma);
798 EXPECT_TRUE(me != a);
799 EXPECT_TRUE(a != me);
800
801 log->push_back("---");
802 }
803 // clang-format off
804 EXPECT_EQ(V("0:17. explicit constructor",
805 "1:42. explicit constructor",
806 "2:17. copy constructor (from 0:17)",
807 "---",
808 "operator== 2:17, 0:17",
809 "operator== 0:17, 2:17",
810 "operator== 2:17, 1:42",
811 "operator== 1:42, 2:17",
812 // No operator should be called when comparing to empty.
813 "operator!= 2:17, 0:17",
814 "operator!= 0:17, 2:17",
815 "operator!= 2:17, 1:42",
816 "operator!= 1:42, 2:17",
817 // No operator should be called when comparing to empty.
818 "---",
819 "2:17. destructor",
820 "1:42. destructor",
821 "0:17. destructor"),
822 *log);
823 // clang-format on
824}
825
Karl Wibergbe579832015-11-10 22:34:18 +0100826TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200827 auto log = Logger::Setup();
828 {
829 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100830 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200831 log->push_back("---");
832 swap(x1, x2); // Swap full <-> full.
833 swap(y1, y2); // Swap full <-> empty.
834 swap(z1, z2); // Swap empty <-> empty.
835 log->push_back("---");
836 }
837 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
838 "2:17. copy constructor (from 0:17)",
839 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700840 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
841 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
842 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200843 "1:42. destructor", "0:17. destructor"),
844 *log);
845}
846
deadbeef81baed32017-02-10 18:11:11 -0800847TEST(OptionalTest, TestMoveValue) {
848 auto log = Logger::Setup();
849 {
850 Optional<Logger> x(Logger(42));
851 log->push_back("---");
Danil Chapovalov57ff2732018-03-28 11:25:15 +0200852 Logger moved = std::move(x.value());
deadbeef81baed32017-02-10 18:11:11 -0800853 log->push_back("---");
854 }
855 EXPECT_EQ(
856 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)",
857 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---",
858 "2:42. destructor", "1:42. destructor"),
859 *log);
860}
861
Danil Chapovalov9dce71b2018-06-11 07:48:31 +0000862// Nice printing available only when GTEST aware ABSL is present
863#ifdef GTEST_HAS_ABSL
864#define MaybeTestPrintTo TestPrintTo
865#define MaybeTestUnprintablePrintTo TestUnprintablePrintTo
866#else
867#define MaybeTestPrintTo DISABLED_TestPrintTo
868#define MaybeTestUnprintablePrintTo DISABLED_TestUnprintablePrintTo
869#endif
870TEST(OptionalTest, MaybeTestPrintTo) {
871 constexpr char kEmptyOptionalMessage[] = "(nullopt)";
ossue5c27a52017-02-20 04:41:42 -0800872 const Optional<MyUnprintableType> empty_unprintable;
873 const Optional<MyPrintableType> empty_printable;
874 const Optional<MyOstreamPrintableType> empty_ostream_printable;
875 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable));
876 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable));
877 EXPECT_EQ(kEmptyOptionalMessage,
878 ::testing::PrintToString(empty_ostream_printable));
Danil Chapovalov9dce71b2018-06-11 07:48:31 +0000879 EXPECT_NE("(1)", ::testing::PrintToString(Optional<MyUnprintableType>({1})));
880 EXPECT_NE("(1)", ::testing::PrintToString(Optional<MyPrintableType>({1})));
881 EXPECT_EQ("(The value is 1)",
ossue5c27a52017-02-20 04:41:42 -0800882 ::testing::PrintToString(Optional<MyPrintableType>({1})));
Danil Chapovalov9dce71b2018-06-11 07:48:31 +0000883 EXPECT_EQ("(1)",
ossue5c27a52017-02-20 04:41:42 -0800884 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1})));
885}
886
Danil Chapovalov9dce71b2018-06-11 07:48:31 +0000887TEST(OptionalTest, MaybeTestUnprintablePrintTo) {
888 struct UnprintableType {
889 uint8_t value[5];
890 };
891 Optional<UnprintableType> opt({0xa1, 0xb2, 0xc3, 0xd4, 0xe5});
892 EXPECT_EQ("(5-byte object <A1-B2 C3-D4 E5>)", ::testing::PrintToString(opt));
893}
894
ossue5c27a52017-02-20 04:41:42 -0800895void UnusedFunctionWorkaround() {
896 // These are here to ensure we don't get warnings about ostream and PrintTo
897 // for MyPrintableType never getting called.
898 const MyPrintableType dont_warn{17};
899 const MyOstreamPrintableType dont_warn2{18};
900 std::stringstream sstr;
901 sstr << dont_warn;
902 PrintTo(dont_warn, &sstr);
903 sstr << dont_warn2;
904}
905
Karl Wiberg6e587202015-10-21 12:43:56 +0200906} // namespace rtc