blob: 8f2f7fd1f0f913cd55f8df1ff9bdebf619aba670 [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
kjellandere96c45b2017-06-30 10:45:21 -070017#include "webrtc/rtc_base/gunit.h"
18#include "webrtc/rtc_base/optional.h"
Karl Wiberg6e587202015-10-21 12:43:56 +020019
20namespace rtc {
21
22namespace {
23
ossue5c27a52017-02-20 04:41:42 -080024struct MyUnprintableType {
25 int value;
26};
27
28struct MyPrintableType {
29 int value;
30};
31
32struct MyOstreamPrintableType {
33 int value;
34};
35
36void PrintTo(const MyPrintableType& mpt, std::ostream* os) {
37 *os << "The value is " << mpt.value;
38}
39
40std::ostream& operator<<(std::ostream& os,
41 const MyPrintableType& mpt) {
42 os << mpt.value;
43 return os;
44}
45
46std::ostream& operator<<(std::ostream& os,
47 const MyOstreamPrintableType& mpt) {
48 os << mpt.value;
49 return os;
50}
51
Karl Wiberg6e587202015-10-21 12:43:56 +020052// Class whose instances logs various method calls (constructor, destructor,
53// etc.). Each instance has a unique ID (a simple global sequence number) and
54// an origin ID. When a copy is made, the new object gets a fresh ID but copies
55// the origin ID from the original. When a new Logger is created from scratch,
56// it gets a fresh ID, and the origin ID is the same as the ID (default
57// constructor) or given as an argument (explicit constructor).
58class Logger {
59 public:
kwibergb2137952016-03-17 08:38:12 -070060 Logger() : id_(g_next_id++), origin_(id_) { Log("default constructor"); }
61 explicit Logger(int origin) : id_(g_next_id++), origin_(origin) {
Karl Wiberg6e587202015-10-21 12:43:56 +020062 Log("explicit constructor");
63 }
danilchap9e83c972016-10-18 04:07:18 -070064 Logger(int origin, const Logger& pass_by_ref, Logger pass_by_value)
65 : id_(g_next_id++), origin_(origin) {
66 Log("multi parameter constructor");
67 }
kwibergb2137952016-03-17 08:38:12 -070068 Logger(const Logger& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020069 LogFrom("copy constructor", other);
70 }
kwibergb2137952016-03-17 08:38:12 -070071 Logger(Logger&& other) : id_(g_next_id++), origin_(other.origin_) {
Karl Wiberg6e587202015-10-21 12:43:56 +020072 LogFrom("move constructor", other);
73 }
74 ~Logger() { Log("destructor"); }
75 Logger& operator=(const Logger& other) {
76 origin_ = other.origin_;
77 LogFrom("operator= copy", other);
78 return *this;
79 }
80 Logger& operator=(Logger&& other) {
81 origin_ = other.origin_;
82 LogFrom("operator= move", other);
83 return *this;
84 }
85 friend void swap(Logger& a, Logger& b) {
86 using std::swap;
87 swap(a.origin_, b.origin_);
88 Log2("swap", a, b);
89 }
90 friend bool operator==(const Logger& a, const Logger& b) {
91 Log2("operator==", a, b);
92 return a.origin_ == b.origin_;
93 }
94 friend bool operator!=(const Logger& a, const Logger& b) {
95 Log2("operator!=", a, b);
96 return a.origin_ != b.origin_;
97 }
98 void Foo() { Log("Foo()"); }
99 void Foo() const { Log("Foo() const"); }
jbauch555604a2016-04-26 03:13:22 -0700100 static std::unique_ptr<std::vector<std::string>> Setup() {
101 std::unique_ptr<std::vector<std::string>> s(new std::vector<std::string>);
kwibergb2137952016-03-17 08:38:12 -0700102 g_log = s.get();
103 g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200104 return s;
105 }
106
107 private:
108 int id_;
109 int origin_;
kwibergb2137952016-03-17 08:38:12 -0700110 static std::vector<std::string>* g_log;
111 static int g_next_id;
Karl Wiberg6e587202015-10-21 12:43:56 +0200112 void Log(const char* msg) const {
113 std::ostringstream oss;
114 oss << id_ << ':' << origin_ << ". " << msg;
kwibergb2137952016-03-17 08:38:12 -0700115 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200116 }
117 void LogFrom(const char* msg, const Logger& other) const {
118 std::ostringstream oss;
119 oss << id_ << ':' << origin_ << ". " << msg << " (from " << other.id_ << ':'
120 << other.origin_ << ")";
kwibergb2137952016-03-17 08:38:12 -0700121 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200122 }
123 static void Log2(const char* msg, const Logger& a, const Logger& b) {
124 std::ostringstream oss;
125 oss << msg << ' ' << a.id_ << ':' << a.origin_ << ", " << b.id_ << ':'
126 << b.origin_;
kwibergb2137952016-03-17 08:38:12 -0700127 g_log->push_back(oss.str());
Karl Wiberg6e587202015-10-21 12:43:56 +0200128 }
129};
130
kwibergb2137952016-03-17 08:38:12 -0700131std::vector<std::string>* Logger::g_log = nullptr;
132int Logger::g_next_id = 0;
Karl Wiberg6e587202015-10-21 12:43:56 +0200133
134// Append all the other args to the vector pointed to by the first arg.
135template <typename T>
136void VectorAppend(std::vector<T>* v) {}
137template <typename T, typename... Ts>
138void VectorAppend(std::vector<T>* v, const T& e, Ts... es) {
139 v->push_back(e);
140 VectorAppend(v, es...);
141}
142
143// Create a vector of strings. Because we're not allowed to use
144// std::initializer_list.
145template <typename... Ts>
146std::vector<std::string> V(Ts... es) {
147 std::vector<std::string> strings;
148 VectorAppend(&strings, static_cast<std::string>(es)...);
149 return strings;
150}
151
152} // namespace
153
Karl Wibergbe579832015-11-10 22:34:18 +0100154TEST(OptionalTest, TestConstructDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200155 auto log = Logger::Setup();
156 {
Karl Wibergbe579832015-11-10 22:34:18 +0100157 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200158 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700159 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200160 }
kwibergd0404802016-05-09 06:06:05 -0700161 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200162}
163
Karl Wibergbe579832015-11-10 22:34:18 +0100164TEST(OptionalTest, TestConstructCopyEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200165 auto log = Logger::Setup();
166 {
Karl Wibergbe579832015-11-10 22:34:18 +0100167 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200168 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700169 EXPECT_FALSE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200170 auto y = x;
171 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700172 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200173 }
kwibergd0404802016-05-09 06:06:05 -0700174 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200175}
176
Karl Wibergbe579832015-11-10 22:34:18 +0100177TEST(OptionalTest, TestConstructCopyFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200178 auto log = Logger::Setup();
179 {
180 Logger a;
Karl Wibergbe579832015-11-10 22:34:18 +0100181 Optional<Logger> x(a);
Karl Wiberg6e587202015-10-21 12:43:56 +0200182 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700183 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200184 log->push_back("---");
185 auto y = x;
186 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700187 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200188 log->push_back("---");
189 }
190 EXPECT_EQ(V("0:0. default constructor", "1:0. copy constructor (from 0:0)",
191 "---", "2:0. copy constructor (from 1:0)", "---",
192 "2:0. destructor", "1:0. destructor", "0:0. destructor"),
193 *log);
194}
195
Karl Wibergbe579832015-11-10 22:34:18 +0100196TEST(OptionalTest, TestConstructMoveEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200197 auto log = Logger::Setup();
198 {
Karl Wibergbe579832015-11-10 22:34:18 +0100199 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200200 EXPECT_FALSE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700201 EXPECT_FALSE(x.has_value());
kwibergcea7c2f2016-01-07 05:52:04 -0800202 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200203 EXPECT_FALSE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700204 EXPECT_FALSE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200205 }
kwibergd0404802016-05-09 06:06:05 -0700206 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200207}
208
Karl Wibergbe579832015-11-10 22:34:18 +0100209TEST(OptionalTest, TestConstructMoveFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200210 auto log = Logger::Setup();
211 {
Karl Wibergbe579832015-11-10 22:34:18 +0100212 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200213 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700214 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200215 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800216 auto y = std::move(x);
Karl Wiberg6e587202015-10-21 12:43:56 +0200217 EXPECT_TRUE(x);
tereliusf79dbad2017-06-16 06:48:13 -0700218 EXPECT_TRUE(x.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200219 EXPECT_TRUE(y);
tereliusf79dbad2017-06-16 06:48:13 -0700220 EXPECT_TRUE(y.has_value());
Karl Wiberg6e587202015-10-21 12:43:56 +0200221 log->push_back("---");
222 }
223 EXPECT_EQ(
224 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
225 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
226 "2:17. destructor", "1:17. destructor"),
227 *log);
228}
229
Karl Wibergbe579832015-11-10 22:34:18 +0100230TEST(OptionalTest, TestCopyAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200231 auto log = Logger::Setup();
232 {
Karl Wibergbe579832015-11-10 22:34:18 +0100233 Optional<Logger> x, y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200234 x = y;
235 }
kwibergd0404802016-05-09 06:06:05 -0700236 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200237}
238
Karl Wibergbe579832015-11-10 22:34:18 +0100239TEST(OptionalTest, TestCopyAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200240 auto log = Logger::Setup();
241 {
Karl Wibergbe579832015-11-10 22:34:18 +0100242 Optional<Logger> x(Logger(17));
243 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200244 log->push_back("---");
245 x = y;
246 log->push_back("---");
247 }
248 EXPECT_EQ(
249 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700250 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200251 *log);
252}
253
Karl Wibergbe579832015-11-10 22:34:18 +0100254TEST(OptionalTest, TestCopyAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200255 auto log = Logger::Setup();
256 {
Karl Wibergbe579832015-11-10 22:34:18 +0100257 Optional<Logger> x;
258 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200259 log->push_back("---");
260 x = y;
261 log->push_back("---");
262 }
kwibergd0404802016-05-09 06:06:05 -0700263 EXPECT_EQ(
264 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
265 "0:17. destructor", "---", "2:17. copy constructor (from 1:17)", "---",
266 "1:17. destructor", "2:17. destructor"),
267 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200268}
269
Karl Wibergbe579832015-11-10 22:34:18 +0100270TEST(OptionalTest, TestCopyAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200271 auto log = Logger::Setup();
272 {
Karl Wibergbe579832015-11-10 22:34:18 +0100273 Optional<Logger> x(Logger(17));
274 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200275 log->push_back("---");
276 x = y;
277 log->push_back("---");
278 }
279 EXPECT_EQ(
280 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
281 "0:17. destructor", "2:42. explicit constructor",
282 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
283 "1:42. operator= copy (from 3:42)", "---", "3:42. destructor",
284 "1:42. destructor"),
285 *log);
286}
287
Karl Wibergbe579832015-11-10 22:34:18 +0100288TEST(OptionalTest, TestCopyAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200289 auto log = Logger::Setup();
290 {
Karl Wibergbe579832015-11-10 22:34:18 +0100291 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200292 Logger y(17);
293 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100294 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200295 log->push_back("---");
296 }
kwibergd0404802016-05-09 06:06:05 -0700297 EXPECT_EQ(V("0:17. explicit constructor", "---",
298 "1:17. copy constructor (from 0:17)",
299 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
300 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200301 *log);
302}
303
Karl Wibergbe579832015-11-10 22:34:18 +0100304TEST(OptionalTest, TestCopyAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200305 auto log = Logger::Setup();
306 {
Karl Wibergbe579832015-11-10 22:34:18 +0100307 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200308 Logger y(42);
309 log->push_back("---");
Karl Wibergbe579832015-11-10 22:34:18 +0100310 x = Optional<Logger>(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200311 log->push_back("---");
312 }
313 EXPECT_EQ(
314 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
315 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700316 "3:42. copy constructor (from 2:42)",
317 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
318 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200319 *log);
320}
321
Karl Wibergbe579832015-11-10 22:34:18 +0100322TEST(OptionalTest, TestMoveAssignToEmptyFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200323 auto log = Logger::Setup();
324 {
Karl Wibergbe579832015-11-10 22:34:18 +0100325 Optional<Logger> x, y;
kwibergcea7c2f2016-01-07 05:52:04 -0800326 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200327 }
kwibergd0404802016-05-09 06:06:05 -0700328 EXPECT_EQ(V(), *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200329}
330
Karl Wibergbe579832015-11-10 22:34:18 +0100331TEST(OptionalTest, TestMoveAssignToFullFromEmpty) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200332 auto log = Logger::Setup();
333 {
Karl Wibergbe579832015-11-10 22:34:18 +0100334 Optional<Logger> x(Logger(17));
335 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200336 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800337 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200338 log->push_back("---");
339 }
340 EXPECT_EQ(
341 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
kwibergd0404802016-05-09 06:06:05 -0700342 "0:17. destructor", "---", "1:17. destructor", "---"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200343 *log);
344}
345
Karl Wibergbe579832015-11-10 22:34:18 +0100346TEST(OptionalTest, TestMoveAssignToEmptyFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200347 auto log = Logger::Setup();
348 {
Karl Wibergbe579832015-11-10 22:34:18 +0100349 Optional<Logger> x;
350 Optional<Logger> y(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200351 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800352 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200353 log->push_back("---");
354 }
kwibergd0404802016-05-09 06:06:05 -0700355 EXPECT_EQ(
356 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
357 "0:17. destructor", "---", "2:17. move constructor (from 1:17)", "---",
358 "1:17. destructor", "2:17. destructor"),
359 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200360}
361
Karl Wibergbe579832015-11-10 22:34:18 +0100362TEST(OptionalTest, TestMoveAssignToFullFromFull) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200363 auto log = Logger::Setup();
364 {
Karl Wibergbe579832015-11-10 22:34:18 +0100365 Optional<Logger> x(Logger(17));
366 Optional<Logger> y(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200367 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800368 x = std::move(y);
Karl Wiberg6e587202015-10-21 12:43:56 +0200369 log->push_back("---");
370 }
371 EXPECT_EQ(
372 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
373 "0:17. destructor", "2:42. explicit constructor",
374 "3:42. move constructor (from 2:42)", "2:42. destructor", "---",
375 "1:42. operator= move (from 3:42)", "---", "3:42. destructor",
376 "1:42. destructor"),
377 *log);
378}
379
Karl Wibergbe579832015-11-10 22:34:18 +0100380TEST(OptionalTest, TestMoveAssignToEmptyFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200381 auto log = Logger::Setup();
382 {
Karl Wibergbe579832015-11-10 22:34:18 +0100383 Optional<Logger> x;
Karl Wiberg6e587202015-10-21 12:43:56 +0200384 Logger y(17);
385 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800386 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200387 log->push_back("---");
388 }
kwibergd0404802016-05-09 06:06:05 -0700389 EXPECT_EQ(V("0:17. explicit constructor", "---",
390 "1:17. move constructor (from 0:17)",
391 "2:17. move constructor (from 1:17)", "1:17. destructor", "---",
392 "0:17. destructor", "2:17. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200393 *log);
394}
395
Karl Wibergbe579832015-11-10 22:34:18 +0100396TEST(OptionalTest, TestMoveAssignToFullFromT) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200397 auto log = Logger::Setup();
398 {
Karl Wibergbe579832015-11-10 22:34:18 +0100399 Optional<Logger> x(Logger(17));
Karl Wiberg6e587202015-10-21 12:43:56 +0200400 Logger y(42);
401 log->push_back("---");
kwibergcea7c2f2016-01-07 05:52:04 -0800402 x = Optional<Logger>(std::move(y));
Karl Wiberg6e587202015-10-21 12:43:56 +0200403 log->push_back("---");
404 }
405 EXPECT_EQ(
406 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
407 "0:17. destructor", "2:42. explicit constructor", "---",
kwiberg102c6a62015-10-30 02:47:38 -0700408 "3:42. move constructor (from 2:42)",
409 "1:42. operator= move (from 3:42)", "3:42. destructor", "---",
410 "2:42. destructor", "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200411 *log);
412}
413
danilchapc4fd23c2016-10-17 07:16:54 -0700414TEST(OptionalTest, TestResetEmpty) {
415 auto log = Logger::Setup();
416 {
417 Optional<Logger> x;
418 x.reset();
419 }
420 EXPECT_EQ(V(), *log);
421}
422
423TEST(OptionalTest, TestResetFull) {
424 auto log = Logger::Setup();
425 {
426 Optional<Logger> x(Logger(17));
427 log->push_back("---");
428 x.reset();
429 log->push_back("---");
430 }
431 EXPECT_EQ(
432 V("0:17. explicit constructor", "1:17. move constructor (from 0:17)",
433 "0:17. destructor", "---", "1:17. destructor", "---"),
434 *log);
435}
436
danilchap9e83c972016-10-18 04:07:18 -0700437TEST(OptionalTest, TestEmplaceEmptyWithExplicit) {
438 auto log = Logger::Setup();
439 {
440 Optional<Logger> x;
441 log->push_back("---");
442 x.emplace(42);
443 log->push_back("---");
444 }
445 // clang-format off
446 EXPECT_EQ(V("---",
447 "0:42. explicit constructor",
448 "---",
449 "0:42. destructor"),
450 *log);
451 // clang-format on
452}
453
454TEST(OptionalTest, TestEmplaceEmptyWithMultipleParameters) {
455 auto log = Logger::Setup();
456 {
457 Optional<Logger> x;
458 Logger ref(21);
459 Logger value(35);
460 log->push_back("---");
461 x.emplace(42, ref, std::move(value));
462 log->push_back("---");
463 }
464 // clang-format off
465 EXPECT_EQ(V("0:21. explicit constructor",
466 "1:35. explicit constructor",
467 "---",
468 "2:35. move constructor (from 1:35)",
469 "3:42. multi parameter constructor",
470 "2:35. destructor",
471 "---",
472 "1:35. destructor",
473 "0:21. destructor",
474 "3:42. destructor"),
475 *log);
476 // clang-format on
477}
478
479TEST(OptionalTest, TestEmplaceEmptyWithCopy) {
480 auto log = Logger::Setup();
481 {
482 Optional<Logger> x;
483 Logger y(42);
484 log->push_back("---");
485 x.emplace(y);
486 log->push_back("---");
487 }
488 // clang-format off
489 EXPECT_EQ(V("0:42. explicit constructor",
490 "---",
491 "1:42. copy constructor (from 0:42)",
492 "---",
493 "0:42. destructor",
494 "1:42. destructor"),
495 *log);
496 // clang-format on
497}
498
499TEST(OptionalTest, TestEmplaceEmptyWithMove) {
500 auto log = Logger::Setup();
501 {
502 Optional<Logger> x;
503 Logger y(42);
504 log->push_back("---");
505 x.emplace(std::move(y));
506 log->push_back("---");
507 }
508 // clang-format off
509 EXPECT_EQ(V("0:42. explicit constructor",
510 "---",
511 "1:42. move constructor (from 0:42)",
512 "---",
513 "0:42. destructor",
514 "1:42. destructor"),
515 *log);
516 // clang-format on
517}
518
519TEST(OptionalTest, TestEmplaceFullWithExplicit) {
520 auto log = Logger::Setup();
521 {
522 Optional<Logger> x(Logger(17));
523 log->push_back("---");
524 x.emplace(42);
525 log->push_back("---");
526 }
527 // clang-format off
528 EXPECT_EQ(
529 V("0:17. explicit constructor",
530 "1:17. move constructor (from 0:17)",
531 "0:17. destructor",
532 "---",
533 "1:17. destructor",
534 "2:42. explicit constructor",
535 "---",
536 "2:42. destructor"),
537 *log);
538 // clang-format on
539}
540
541TEST(OptionalTest, TestEmplaceFullWithMultipleParameters) {
542 auto log = Logger::Setup();
543 {
544 Optional<Logger> x(Logger(17));
545 Logger ref(21);
546 Logger value(35);
547 log->push_back("---");
548 x.emplace(42, ref, std::move(value));
549 log->push_back("---");
550 }
551 // clang-format off
552 EXPECT_EQ(V("0:17. explicit constructor",
553 "1:17. move constructor (from 0:17)",
554 "0:17. destructor",
555 "2:21. explicit constructor",
556 "3:35. explicit constructor",
557 "---",
558 "1:17. destructor",
559 "4:35. move constructor (from 3:35)",
560 "5:42. multi parameter constructor",
561 "4:35. destructor",
562 "---",
563 "3:35. destructor",
564 "2:21. destructor",
565 "5:42. destructor"),
566 *log);
567 // clang-format on
568}
569
570TEST(OptionalTest, TestEmplaceFullWithCopy) {
571 auto log = Logger::Setup();
572 {
573 Optional<Logger> x(Logger(17));
574 Logger y(42);
575 log->push_back("---");
576 x.emplace(y);
577 log->push_back("---");
578 }
579 // clang-format off
580 EXPECT_EQ(V("0:17. explicit constructor",
581 "1:17. move constructor (from 0:17)",
582 "0:17. destructor",
583 "2:42. explicit constructor",
584 "---",
585 "1:17. destructor",
586 "3:42. copy constructor (from 2:42)",
587 "---",
588 "2:42. destructor",
589 "3:42. destructor"),
590 *log);
591 // clang-format on
592}
593
594TEST(OptionalTest, TestEmplaceFullWithMove) {
595 auto log = Logger::Setup();
596 {
597 Optional<Logger> x(Logger(17));
598 Logger y(42);
599 log->push_back("---");
600 x.emplace(std::move(y));
601 log->push_back("---");
602 }
603 // clang-format off
604 EXPECT_EQ(V("0:17. explicit constructor",
605 "1:17. move constructor (from 0:17)",
606 "0:17. destructor",
607 "2:42. explicit constructor",
608 "---",
609 "1:17. destructor",
610 "3:42. move constructor (from 2:42)",
611 "---",
612 "2:42. destructor",
613 "3:42. destructor"),
614 *log);
615 // clang-format on
616}
617
Karl Wibergbe579832015-11-10 22:34:18 +0100618TEST(OptionalTest, TestDereference) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200619 auto log = Logger::Setup();
620 {
Karl Wibergbe579832015-11-10 22:34:18 +0100621 Optional<Logger> x(Logger(42));
Karl Wiberg6e587202015-10-21 12:43:56 +0200622 const auto& y = x;
623 log->push_back("---");
624 x->Foo();
625 y->Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800626 std::move(x)->Foo();
627 std::move(y)->Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200628 log->push_back("---");
629 (*x).Foo();
630 (*y).Foo();
kwibergcea7c2f2016-01-07 05:52:04 -0800631 (*std::move(x)).Foo();
632 (*std::move(y)).Foo();
Karl Wiberg6e587202015-10-21 12:43:56 +0200633 log->push_back("---");
tereliusf79dbad2017-06-16 06:48:13 -0700634 x.value().Foo();
635 y.value().Foo();
636 std::move(x).value().Foo();
637 std::move(y).value().Foo();
638 log->push_back("---");
Karl Wiberg6e587202015-10-21 12:43:56 +0200639 }
tereliusf79dbad2017-06-16 06:48:13 -0700640 // clang-format off
Karl Wiberg6e587202015-10-21 12:43:56 +0200641 EXPECT_EQ(V("0:42. explicit constructor",
tereliusf79dbad2017-06-16 06:48:13 -0700642 "1:42. move constructor (from 0:42)",
643 "0:42. destructor",
644 "---",
645 "1:42. Foo()",
646 "1:42. Foo() const",
647 "1:42. Foo()",
648 "1:42. Foo() const",
649 "---",
650 "1:42. Foo()",
651 "1:42. Foo() const",
652 "1:42. Foo()",
653 "1:42. Foo() const",
654 "---",
655 "1:42. Foo()",
656 "1:42. Foo() const",
657 "1:42. Foo()",
658 "1:42. Foo() const",
659 "---",
660 "1:42. destructor"),
Karl Wiberg6e587202015-10-21 12:43:56 +0200661 *log);
tereliusf79dbad2017-06-16 06:48:13 -0700662 // clang-format on
Karl Wiberg6e587202015-10-21 12:43:56 +0200663}
664
Karl Wibergbe579832015-11-10 22:34:18 +0100665TEST(OptionalTest, TestDereferenceWithDefault) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200666 auto log = Logger::Setup();
667 {
668 const Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100669 Optional<Logger> x(a);
670 Optional<Logger> y;
Karl Wiberg6e587202015-10-21 12:43:56 +0200671 log->push_back("-1-");
672 EXPECT_EQ(a, x.value_or(Logger(42)));
673 log->push_back("-2-");
674 EXPECT_EQ(b, y.value_or(Logger(42)));
675 log->push_back("-3-");
Karl Wibergbe579832015-11-10 22:34:18 +0100676 EXPECT_EQ(a, Optional<Logger>(Logger(17)).value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200677 log->push_back("-4-");
Karl Wibergbe579832015-11-10 22:34:18 +0100678 EXPECT_EQ(b, Optional<Logger>().value_or(b));
Karl Wiberg6e587202015-10-21 12:43:56 +0200679 log->push_back("-5-");
680 }
681 EXPECT_EQ(
682 V("0:17. explicit constructor", "1:42. explicit constructor",
kwibergd0404802016-05-09 06:06:05 -0700683 "2:17. copy constructor (from 0:17)", "-1-",
684 "3:42. explicit constructor", "operator== 0:17, 2:17",
685 "3:42. destructor", "-2-", "4:42. explicit constructor",
686 "operator== 1:42, 4:42", "4:42. destructor", "-3-",
687 "5:17. explicit constructor", "6:17. move constructor (from 5:17)",
688 "operator== 0:17, 6:17", "6:17. destructor", "5:17. destructor", "-4-",
689 "operator== 1:42, 1:42", "-5-", "2:17. destructor", "1:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200690 "0:17. destructor"),
691 *log);
692}
693
Karl Wibergbe579832015-11-10 22:34:18 +0100694TEST(OptionalTest, TestEquality) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200695 auto log = Logger::Setup();
696 {
697 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100698 Optional<Logger> ma1(a), ma2(a), mb(b), me1, me2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200699 log->push_back("---");
700 EXPECT_EQ(ma1, ma1);
701 EXPECT_EQ(ma1, ma2);
702 EXPECT_NE(ma1, mb);
703 EXPECT_NE(ma1, me1);
704 EXPECT_EQ(me1, me1);
705 EXPECT_EQ(me1, me2);
706 log->push_back("---");
707 }
kwibergd0404802016-05-09 06:06:05 -0700708 EXPECT_EQ(
709 V("0:17. explicit constructor", "1:42. explicit constructor",
710 "2:17. copy constructor (from 0:17)",
711 "3:17. copy constructor (from 0:17)",
712 "4:42. copy constructor (from 1:42)", "---", "operator== 2:17, 2:17",
713 "operator== 2:17, 3:17", "operator!= 2:17, 4:42", "---",
714 "4:42. destructor", "3:17. destructor", "2:17. destructor",
715 "1:42. destructor", "0:17. destructor"),
716 *log);
Karl Wiberg6e587202015-10-21 12:43:56 +0200717}
718
danilchape0370602016-10-20 00:58:15 -0700719TEST(OptionalTest, TestEqualityWithObject) {
720 auto log = Logger::Setup();
721 {
722 Logger a(17), b(42);
723 Optional<Logger> ma(a), me;
724 // Using operator== and operator!= explicetly instead of EXPECT_EQ/EXPECT_NE
725 // macros because those operators are under test.
726 log->push_back("---");
727
728 EXPECT_TRUE(ma == a);
729 EXPECT_TRUE(a == ma);
730 EXPECT_FALSE(ma == b);
731 EXPECT_FALSE(b == ma);
732 EXPECT_FALSE(me == a);
733 EXPECT_FALSE(a == me);
734
735 EXPECT_FALSE(ma != a);
736 EXPECT_FALSE(a != ma);
737 EXPECT_TRUE(ma != b);
738 EXPECT_TRUE(b != ma);
739 EXPECT_TRUE(me != a);
740 EXPECT_TRUE(a != me);
741
742 log->push_back("---");
743 }
744 // clang-format off
745 EXPECT_EQ(V("0:17. explicit constructor",
746 "1:42. explicit constructor",
747 "2:17. copy constructor (from 0:17)",
748 "---",
749 "operator== 2:17, 0:17",
750 "operator== 0:17, 2:17",
751 "operator== 2:17, 1:42",
752 "operator== 1:42, 2:17",
753 // No operator should be called when comparing to empty.
754 "operator!= 2:17, 0:17",
755 "operator!= 0:17, 2:17",
756 "operator!= 2:17, 1:42",
757 "operator!= 1:42, 2:17",
758 // No operator should be called when comparing to empty.
759 "---",
760 "2:17. destructor",
761 "1:42. destructor",
762 "0:17. destructor"),
763 *log);
764 // clang-format on
765}
766
Karl Wibergbe579832015-11-10 22:34:18 +0100767TEST(OptionalTest, TestSwap) {
Karl Wiberg6e587202015-10-21 12:43:56 +0200768 auto log = Logger::Setup();
769 {
770 Logger a(17), b(42);
Karl Wibergbe579832015-11-10 22:34:18 +0100771 Optional<Logger> x1(a), x2(b), y1(a), y2, z1, z2;
Karl Wiberg6e587202015-10-21 12:43:56 +0200772 log->push_back("---");
773 swap(x1, x2); // Swap full <-> full.
774 swap(y1, y2); // Swap full <-> empty.
775 swap(z1, z2); // Swap empty <-> empty.
776 log->push_back("---");
777 }
778 EXPECT_EQ(V("0:17. explicit constructor", "1:42. explicit constructor",
779 "2:17. copy constructor (from 0:17)",
780 "3:42. copy constructor (from 1:42)",
kwibergd0404802016-05-09 06:06:05 -0700781 "4:17. copy constructor (from 0:17)", "---", "swap 2:42, 3:17",
782 "5:17. move constructor (from 4:17)", "4:17. destructor", "---",
783 "5:17. destructor", "3:17. destructor", "2:42. destructor",
Karl Wiberg6e587202015-10-21 12:43:56 +0200784 "1:42. destructor", "0:17. destructor"),
785 *log);
786}
787
deadbeef81baed32017-02-10 18:11:11 -0800788TEST(OptionalTest, TestMoveValue) {
789 auto log = Logger::Setup();
790 {
791 Optional<Logger> x(Logger(42));
792 log->push_back("---");
793 Logger moved = x.MoveValue();
794 log->push_back("---");
795 }
796 EXPECT_EQ(
797 V("0:42. explicit constructor", "1:42. move constructor (from 0:42)",
798 "0:42. destructor", "---", "2:42. move constructor (from 1:42)", "---",
799 "2:42. destructor", "1:42. destructor"),
800 *log);
801}
802
ossue5c27a52017-02-20 04:41:42 -0800803TEST(OptionalTest, TestPrintTo) {
804 constexpr char kEmptyOptionalMessage[] = "<empty optional>";
805 const Optional<MyUnprintableType> empty_unprintable;
806 const Optional<MyPrintableType> empty_printable;
807 const Optional<MyOstreamPrintableType> empty_ostream_printable;
808 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_unprintable));
809 EXPECT_EQ(kEmptyOptionalMessage, ::testing::PrintToString(empty_printable));
810 EXPECT_EQ(kEmptyOptionalMessage,
811 ::testing::PrintToString(empty_ostream_printable));
812 EXPECT_NE("1", ::testing::PrintToString(Optional<MyUnprintableType>({1})));
813 EXPECT_NE("1", ::testing::PrintToString(Optional<MyPrintableType>({1})));
814 EXPECT_EQ("The value is 1",
815 ::testing::PrintToString(Optional<MyPrintableType>({1})));
816 EXPECT_EQ("1",
817 ::testing::PrintToString(Optional<MyOstreamPrintableType>({1})));
818}
819
820void UnusedFunctionWorkaround() {
821 // These are here to ensure we don't get warnings about ostream and PrintTo
822 // for MyPrintableType never getting called.
823 const MyPrintableType dont_warn{17};
824 const MyOstreamPrintableType dont_warn2{18};
825 std::stringstream sstr;
826 sstr << dont_warn;
827 PrintTo(dont_warn, &sstr);
828 sstr << dont_warn2;
829}
830
Karl Wiberg6e587202015-10-21 12:43:56 +0200831} // namespace rtc