Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(356)

Side by Side Diff: base/optional_unittest.cc

Issue 1245163002: Base: add Optional<T>. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: closer to spec implementation Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« base/optional.h ('K') | « base/optional.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "base/optional.h"
6
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace base {
10
11 namespace {
12
13 // Object used to test complex object with Optional<T> in addition of the move
14 // semantics.
15 class TestObject {
16 public:
17 enum class State {
18 DEFAULT_CONSTRUCTED,
19 VALUE_CONSTRUCTED,
20 COPY_CONSTRUCTED,
21 MOVE_CONSTRUCTED,
22 MOVED_FROM,
23 };
24
25 TestObject() : foo_(0), bar_(0.0), state_(State::DEFAULT_CONSTRUCTED) { }
26
27 TestObject(int foo, double bar)
28 : foo_(foo),
29 bar_(bar),
30 state_(State::VALUE_CONSTRUCTED) { }
31
32 TestObject(const TestObject& other)
33 : foo_(other.foo_),
34 bar_(other.bar_),
35 state_(State::COPY_CONSTRUCTED) {
36 }
37
38 TestObject(TestObject&& other)
39 : foo_(std::move(other.foo_)),
40 bar_(std::move(other.bar_)),
41 state_(State::MOVE_CONSTRUCTED) {
42 other.state_ = State::MOVED_FROM;
43 }
44
45 TestObject& operator=(const TestObject& other) {
46 foo_ = other.foo_;
47 bar_ = other.bar_;
48 state_ = State::COPY_CONSTRUCTED;
49 return *this;
50 }
51
52 bool operator==(const TestObject& other) const {
53 return foo_ == other.foo_ && bar_ == other.bar_;
54 }
55
56 int foo() const { return foo_; }
57 State state() const { return state_; }
58
59 private:
60 int foo_;
61 double bar_;
62 State state_;
63 };
64
65 } // anonymous namespace
66
67 TEST(OptionalTest, DefaultConstructor) {
68 {
69 Optional<float> o;
70 EXPECT_FALSE(o);
71 }
72
73 {
74 Optional<std::string> o;
75 EXPECT_FALSE(o);
76 }
77
78 {
79 Optional<TestObject> o;
80 EXPECT_FALSE(o);
81 }
82 }
83
84
85 TEST(OptionalTest, ValueConstructor) {
86 {
87 Optional<float> o(0.1f);
88 EXPECT_TRUE(o);
89 EXPECT_EQ(o.value(), 0.1f);
90 }
91
92 {
93 Optional<std::string> o("foo");
94 EXPECT_TRUE(o);
95 EXPECT_EQ(o.value(), "foo");
96 }
97
98 {
99 Optional<TestObject> o(TestObject(3, 0.1));
100 EXPECT_TRUE(o);
101 EXPECT_EQ(o.value(), TestObject(3, 0.1));
102 }
103 }
104
105 TEST(OptionalTest, CopyConstructor) {
106 {
107 Optional<float> first(0.1f);
108 Optional<float> other(first);
109
110 EXPECT_TRUE(other);
111 EXPECT_EQ(other.value(), 0.1f);
112 EXPECT_EQ(first, other);
113 }
114
115 {
116 Optional<std::string> first("foo");
117 Optional<std::string> other(first);
118
119 EXPECT_TRUE(other);
120 EXPECT_EQ(other.value(), "foo");
121 EXPECT_EQ(first, other);
122 }
123
124 {
125 Optional<TestObject> first(TestObject(3, 0.1));
126 Optional<TestObject> other(first);
127
128 EXPECT_TRUE(other);
129 EXPECT_EQ(other.value(), TestObject(3, 0.1));
130 EXPECT_EQ(first, other);
131 }
132 }
133
134 TEST(OptionalTest, MoveConstructor) {
135 {
136 Optional<float> first(0.1f);
137 Optional<float> second(std::move(first));
138
139 EXPECT_TRUE(second);
140 EXPECT_EQ(second.value(), 0.1f);
141
142 EXPECT_TRUE(first);
143 }
144
145 {
146 Optional<std::string> first("foo");
147 Optional<std::string> second(std::move(first));
148
149 EXPECT_TRUE(second);
150 EXPECT_EQ("foo", second.value());
151
152 EXPECT_TRUE(first);
153 }
154
155 {
156 Optional<TestObject> first(TestObject(3, 0.1));
157 Optional<TestObject> second(std::move(first));
158
159 EXPECT_TRUE(second);
160 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, second->state());
161 EXPECT_EQ(TestObject(3, 0.1), second.value());
162
163 EXPECT_TRUE(first);
164 EXPECT_EQ(TestObject::State::MOVED_FROM, first->state());
165 }
166 }
167
168 TEST(OptionalTest, MoveValueConstructor) {
169 {
170 Optional<float> first(0.1f);
171 Optional<float> second(std::move(first.value()));
172
173 EXPECT_TRUE(second);
174 EXPECT_EQ(second.value(), 0.1f);
175
176 EXPECT_TRUE(first);
177 }
178
179 {
180 Optional<std::string> first("foo");
181 Optional<std::string> second(std::move(first.value()));
182
183 EXPECT_TRUE(second);
184 EXPECT_EQ("foo", second.value());
185
186 EXPECT_TRUE(first);
187 }
188
189 {
190 Optional<TestObject> first(TestObject(3, 0.1));
191 Optional<TestObject> second(std::move(first.value()));
192
193 EXPECT_TRUE(second);
194 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, second->state());
195 EXPECT_EQ(TestObject(3, 0.1), second.value());
196
197 EXPECT_TRUE(first);
198 EXPECT_EQ(TestObject::State::MOVED_FROM, first->state());
199 }
200 }
201
202 TEST(OptionalTest, ConstructorForwardArguments) {
203 {
204 Optional<float> a(base::in_place, 0.1f);
205 EXPECT_TRUE(a);
206 EXPECT_EQ(0.1f, a.value());
207 }
208
209 {
210 Optional<std::string> a(base::in_place, "foo");
211 EXPECT_TRUE(a);
212 EXPECT_EQ("foo", a.value());
213 }
214
215 {
216 Optional<TestObject> a(base::in_place, 0, 0.1);
217 EXPECT_TRUE(a);
218 EXPECT_EQ(TestObject(0, 0.1), a.value());
219 }
220 }
221
222 TEST(OptionalTest, Equals) {
223 {
224 Optional<float> a(0.1f);
225 Optional<float> b(0.1f);
226 EXPECT_EQ(a, b);
227 }
228
229 {
230 Optional<std::string> a("foo");
231 Optional<std::string> b("foo");
232 EXPECT_EQ(a, b);
233 }
234
235 {
236 Optional<TestObject> a(TestObject(3, 0.1));
237 Optional<TestObject> b(TestObject(3, 0.1));
238 EXPECT_EQ(a, b);
239 }
240 }
241
242 TEST(OptionalTest, EqualsNull) {
243 {
244 Optional<float> a(0.1f);
245 Optional<float> b(0.2f);
246 a = base::nullopt;
247 b = base::nullopt;
248 EXPECT_EQ(a, b);
249 }
250
251 {
252 Optional<std::string> a("foo");
253 Optional<std::string> b("bar");
254 a = base::nullopt;
255 b = base::nullopt;
256 EXPECT_EQ(a, b);
257 }
258
259 {
260 Optional<TestObject> a(TestObject(3, 0.1));
261 Optional<TestObject> b(TestObject(4, 1.0));
262 a = base::nullopt;
263 b = base::nullopt;
264 EXPECT_EQ(a, b);
265 }
266 }
267
268 TEST(OptionalTest, NotEquals) {
269 {
270 Optional<float> a(0.1f);
271 Optional<float> b(0.2f);
272 EXPECT_NE(a, b);
273 }
274
275 {
276 Optional<std::string> a("foo");
277 Optional<std::string> b("bar");
278 EXPECT_NE(a, b);
279 }
280
281 {
282 Optional<TestObject> a(TestObject(3, 0.1));
283 Optional<TestObject> b(TestObject(4, 1.0));
284 EXPECT_NE(a, b);
285 }
286 }
287
288 TEST(OptionalTest, NotEqualsNull) {
289 {
290 Optional<float> a(0.1f);
291 Optional<float> b(0.1f);
292 b = base::nullopt;
293 EXPECT_NE(a, b);
294 }
295
296 {
297 Optional<std::string> a("foo");
298 Optional<std::string> b("foo");
299 b = base::nullopt;
300 EXPECT_NE(a, b);
301 }
302
303 {
304 Optional<TestObject> a(TestObject(3, 0.1));
305 Optional<TestObject> b(TestObject(3, 0.1));
306 b = base::nullopt;
307 EXPECT_NE(a, b);
308 }
309 }
310
311 TEST(OptionalTest, AssignValue) {
312 {
313 Optional<float> a;
314 EXPECT_FALSE(a);
315 a = 0.1f;
316 EXPECT_TRUE(a);
317
318 Optional<float> b(0.1f);
319 EXPECT_TRUE(a == b);
320 }
321
322 {
323 // Using |const char*| because |std::string| can't be assigned string
324 // literals because of the decay-only perfect forwarding assignment rule.
325 Optional<const char*> a;
326 EXPECT_FALSE(a);
327 a = "foo";
328 EXPECT_TRUE(a);
329
330 Optional<const char*> b("foo");
331 EXPECT_TRUE(a == b);
332 }
333
334 {
335 Optional<TestObject> a;
336 EXPECT_FALSE(a);
337 a = TestObject(3, 0.1);
338 EXPECT_TRUE(a);
339
340 Optional<TestObject> b(TestObject(3, 0.1));
341 EXPECT_TRUE(a == b);
342 }
343 }
344
345 TEST(OptionalTest, AssignObject) {
346 {
347 Optional<float> a;
348 Optional<float> b(0.1f);
349 a = b;
350
351 EXPECT_TRUE(a);
352 EXPECT_EQ(a.value(), 0.1f);
353 EXPECT_EQ(a, b);
354 }
355
356 {
357 Optional<std::string> a;
358 Optional<std::string> b("foo");
359 a = b;
360
361 EXPECT_TRUE(a);
362 EXPECT_EQ(a.value(), "foo");
363 EXPECT_EQ(a, b);
364 }
365
366 {
367 Optional<TestObject> a;
368 Optional<TestObject> b(TestObject(3, 0.1));
369 a = b;
370
371 EXPECT_TRUE(a);
372 EXPECT_EQ(a.value(), TestObject(3, 0.1));
373 EXPECT_EQ(a, b);
374 }
375 }
376
377 TEST(OptionalTest, AssignObject_rvalue) {
378 {
379 Optional<float> a;
380 Optional<float> b(0.1f);
381 a = std::move(b);
382
383 EXPECT_TRUE(a);
384 EXPECT_TRUE(b);
385 EXPECT_EQ(0.1f, a.value());
386 }
387
388 {
389 Optional<std::string> a;
390 Optional<std::string> b("foo");
391 a = std::move(b);
392
393 EXPECT_TRUE(a);
394 EXPECT_TRUE(b);
395 EXPECT_EQ("foo", a.value());
396 }
397
398 {
399 Optional<TestObject> a;
400 Optional<TestObject> b(TestObject(3, 0.1));
401 a = std::move(b);
402
403 EXPECT_TRUE(a);
404 EXPECT_TRUE(b);
405 EXPECT_EQ(TestObject(3, 0.1), a.value());
406
407 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED, a->state());
408 EXPECT_EQ(TestObject::State::MOVED_FROM, b->state());
409 }
410 }
411
412 TEST(OptionalTest, OperatorStar) {
413 {
414 Optional<float> a(0.1f);
415 EXPECT_EQ(a.value(), *a);
416 }
417
418 {
419 Optional<std::string> a("foo");
420 EXPECT_EQ(a.value(), *a);
421 }
422
423 {
424 Optional<TestObject> a(TestObject(3, 0.1));
425 EXPECT_EQ(a.value(), *a);
426 }
427 }
428
429 TEST(OptionalTest, OperatorStar_rvalue) {
430 EXPECT_EQ(0.1f, *Optional<float>(0.1f));
431 EXPECT_EQ("foo", *Optional<const char*>("foo"));
432 EXPECT_EQ(TestObject(3, 0.1), *Optional<TestObject>(TestObject(3, 0.1)));
433 }
434
435 TEST(OptionalTest, OperatorArrow) {
436 Optional<TestObject> a(TestObject(3, 0.1));
437 EXPECT_EQ(a->foo(), 3);
438 }
439
440 TEST(OptionalTest, Value_rvalue) {
441 EXPECT_EQ(0.1f, Optional<float>(0.1f).value());
442 EXPECT_EQ("foo", Optional<const char*>("foo").value());
443 EXPECT_EQ(TestObject(3, 0.1),
444 Optional<TestObject>(TestObject(3, 0.1)).value());
445 }
446
447 TEST(OptionalTest, ValueOr) {
448 {
449 Optional<float> a;
450 EXPECT_EQ(0.0f, a.value_or(0.0f));
451
452 a = 0.1f;
453 EXPECT_EQ(0.1f, a.value_or(0.0f));
454
455 a = base::nullopt;
456 EXPECT_EQ(0.0f, a.value_or(0.0f));
457 }
458
459 {
460 // Using |const char*| because |std::string| can't be assigned string
461 // literals because of the decay-only perfect forwarding assignment rule.
462 Optional<const char*> a;
463 EXPECT_EQ("bar", a.value_or("bar"));
464
465 a = "foo";
466 EXPECT_EQ("foo", a.value_or("bar"));
467
468 a = base::nullopt;
469 EXPECT_EQ("bar", a.value_or("bar"));
470 }
471
472 {
473 Optional<TestObject> a;
474 EXPECT_EQ(a.value_or(TestObject(1, 0.3)), TestObject(1, 0.3));
475
476 a = TestObject(3, 0.1);
477 EXPECT_EQ(a.value_or(TestObject(1, 0.3)), TestObject(3, 0.1));
478
479 a = base::nullopt;
480 EXPECT_EQ(a.value_or(TestObject(1, 0.3)), TestObject(1, 0.3));
481 }
482 }
483
484 TEST(OptionalTest, Swap_bothNoValue) {
485 Optional<TestObject> a, b;
486 a.swap(b);
487
488 EXPECT_FALSE(a);
489 EXPECT_FALSE(b);
490 EXPECT_EQ(TestObject(42, 0.42), a.value_or(TestObject(42, 0.42)));
491 EXPECT_EQ(TestObject(42, 0.42), b.value_or(TestObject(42, 0.42)));
492 }
493
494 TEST(OptionalTest, Swap_inHasValue) {
495 Optional<TestObject> a(TestObject(1, 0.3));
496 Optional<TestObject> b;
497 a.swap(b);
498
499 EXPECT_FALSE(a);
500 EXPECT_TRUE(b);
501 EXPECT_EQ(TestObject(42, 0.42), a.value_or(TestObject(42, 0.42)));
502 EXPECT_EQ(TestObject(1, 0.3), b.value_or(TestObject(42, 0.42)));
503 }
504
505 TEST(OptionalTest, Swap_outHasValue) {
506 Optional<TestObject> a;
507 Optional<TestObject> b(TestObject(1, 0.3));
508 a.swap(b);
509
510 EXPECT_TRUE(a);
511 EXPECT_FALSE(b);
512 EXPECT_EQ(TestObject(1, 0.3), a.value_or(TestObject(42, 0.42)));
513 EXPECT_EQ(TestObject(42, 0.42), b.value_or(TestObject(42, 0.42)));
514 }
515
516 TEST(OptionalTest, Swap_bothValue) {
517 Optional<TestObject> a(TestObject(0, 0.1));
518 Optional<TestObject> b(TestObject(1, 0.3));
519 a.swap(b);
520
521 EXPECT_TRUE(a);
522 EXPECT_TRUE(b);
523 EXPECT_EQ(TestObject(1, 0.3), a.value_or(TestObject(42, 0.42)));
524 EXPECT_EQ(TestObject(0, 0.1), b.value_or(TestObject(42, 0.42)));
525 }
526
527 TEST(OptionalTest, Emplace) {
528 {
529 Optional<float> a(0.1f);
530 a.emplace(0.3f);
531
532 EXPECT_TRUE(a);
533 EXPECT_EQ(0.3f, a.value());
534 }
535
536 {
537 Optional<std::string> a("foo");
538 a.emplace("bar");
539
540 EXPECT_TRUE(a);
541 EXPECT_EQ("bar", a.value());
542 }
543
544 {
545 Optional<TestObject> a(TestObject(0, 0.1));
546 a.emplace(TestObject(1, 0.2));
547
548 EXPECT_TRUE(a);
549 EXPECT_EQ(TestObject(1, 0.2), a.value());
550 }
551 }
552
553 // TODO: tests for the operator non-member functions. Some are already present.
554
555 TEST(OptionalTest, MakeOptional) {
556 {
557 Optional<float> o = base::make_optional(32.f);
558 EXPECT_TRUE(o);
559 EXPECT_EQ(32.f, *o);
560
561 float value = 3.f;
562 o = base::make_optional(std::move(value));
563 EXPECT_TRUE(o);
564 EXPECT_EQ(3.f, *o);
565 }
566
567 {
568 Optional<const char*> o = base::make_optional("foo");
569 EXPECT_TRUE(o);
570 EXPECT_EQ("foo", *o);
571
572 const char* value = "bar";
573 o = base::make_optional(std::move(value));
574 EXPECT_TRUE(o);
575 EXPECT_EQ("bar", *o);
576 }
577
578 {
579 Optional<TestObject> o = base::make_optional(TestObject(3, 0.1));
580 EXPECT_TRUE(o);
581 EXPECT_EQ(TestObject(3, 0.1), *o);
582
583 TestObject value = TestObject(0, 0.42);
584 o = base::make_optional(std::move(value));
585 EXPECT_TRUE(o);
586 EXPECT_EQ(TestObject(0, 0.42), *o);
587 EXPECT_EQ(TestObject::State::MOVED_FROM, value.state());
588 EXPECT_EQ(TestObject::State::COPY_CONSTRUCTED, o->state());
589
590 EXPECT_EQ(TestObject::State::MOVE_CONSTRUCTED,
591 base::make_optional(std::move(value))->state());
592 }
593 }
594
595 TEST(OptionalTest, NonMemberSwap_bothNoValue) {
596 Optional<TestObject> a, b;
597 base::swap(a, b);
598
599 EXPECT_FALSE(a);
600 EXPECT_FALSE(b);
601 EXPECT_EQ(TestObject(42, 0.42), a.value_or(TestObject(42, 0.42)));
602 EXPECT_EQ(TestObject(42, 0.42), b.value_or(TestObject(42, 0.42)));
603 }
604
605 TEST(OptionalTest, NonMemberSwap_inHasValue) {
606 Optional<TestObject> a(TestObject(1, 0.3));
607 Optional<TestObject> b;
608 base::swap(a, b);
609
610 EXPECT_FALSE(a);
611 EXPECT_TRUE(b);
612 EXPECT_EQ(TestObject(42, 0.42), a.value_or(TestObject(42, 0.42)));
613 EXPECT_EQ(TestObject(1, 0.3), b.value_or(TestObject(42, 0.42)));
614 }
615
616 TEST(OptionalTest, NonMemberSwap_outHasValue) {
617 Optional<TestObject> a;
618 Optional<TestObject> b(TestObject(1, 0.3));
619 base::swap(a, b);
620
621 EXPECT_TRUE(a);
622 EXPECT_FALSE(b);
623 EXPECT_EQ(TestObject(1, 0.3), a.value_or(TestObject(42, 0.42)));
624 EXPECT_EQ(TestObject(42, 0.42), b.value_or(TestObject(42, 0.42)));
625 }
626
627 TEST(OptionalTest, NonMemberSwap_bothValue) {
628 Optional<TestObject> a(TestObject(0, 0.1));
629 Optional<TestObject> b(TestObject(1, 0.3));
630 base::swap(a, b);
631
632 EXPECT_TRUE(a);
633 EXPECT_TRUE(b);
634 EXPECT_EQ(TestObject(1, 0.3), a.value_or(TestObject(42, 0.42)));
635 EXPECT_EQ(TestObject(0, 0.1), b.value_or(TestObject(42, 0.42)));
636 }
637
638 TEST(OptionalTest, Hash) {
639 // TODO
640 }
641
642 } // namespace base
OLDNEW
« base/optional.h ('K') | « base/optional.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698