GCC Code Coverage Report


Directory: ./
File: TestUniqueRef.cpp
Date: 2026-03-21 20:51:59
Exec Total Coverage
Lines: 70 70 100.0%
Functions: 23 23 100.0%
Branches: 129 426 30.3%

Line Branch Exec Source
1 #include "Shape.hpp"
2 #include "UniqueRef.hpp"
3 #include "Verbose.hpp"
4 #include "compat/gsl14.hpp"
5
6 #include <gmock/gmock.h>
7 #include <vector>
8
9 using namespace testing;
10 using namespace testing::internal;
11
12 // Anonymous namespace for definitions that are local to this file.
13 namespace {
14 template <typename T>
15 using UniqueContainer = std::vector<UniqueRef<T>>;
16
17 // Both refer to the same object (same addresses)
18 template <typename T>
19 1 bool same(const UniqueRef<T>& a, const UniqueRef<T>& b) {
20 1 return &a.get() == &b.get();
21 }
22
23 13 const std::string& name(const Verbose<Circle>& v) { return v.name(); }
24
25 21 const std::string& name(const Verbose<>& v) { return v.name(); }
26
27 3 double area(const Shape& a) { return a.area(); }
28
29 // Print the elements of a container of smart references.
30 template <typename T>
31 2 void print(
32 const UniqueContainer<Verbose<T>>& container,
33 const std::string& prefix = "print: ") {
34
2/2
✓ Branch 9 taken 6 times.
✓ Branch 10 taken 2 times.
8 for (const auto& elem : container) {
35
3/6
✓ Branch 3 taken 6 times.
✗ Branch 4 not taken.
✓ Branch 12 taken 6 times.
✗ Branch 13 not taken.
✓ Branch 18 taken 6 times.
✗ Branch 19 not taken.
6 std::cout << prefix << name(elem) << std::endl;
36
5/16
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
6 EXPECT_THAT(name(elem), Not(HasSubstr("copy")));
37
5/16
✓ Branch 5 taken 6 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 6 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 6 times.
✗ Branch 12 not taken.
✓ Branch 20 taken 6 times.
✗ Branch 21 not taken.
✗ Branch 29 not taken.
✓ Branch 30 taken 6 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 43 not taken.
✗ Branch 44 not taken.
6 EXPECT_THAT(name(elem), Not(HasSubstr("move")));
38 }
39 2 }
40 } // anonymous namespace
41
42 // NOLINTBEGIN(*-avoid-magic-numbers)
43
44 8 TEST(UniqueRef, constructor) {
45
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 auto a = makeUniqueRef<Verbose<Circle>>("one", 1.0);
46
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 auto b = makeUniqueRef<Verbose<Circle>>("two", 2.0);
47 // auto c = UniqueRef<Verbose<Circle>> { }; // no dangling references!
48
49
2/12
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✗ Branch 8 not taken.
✓ Branch 9 taken 1 times.
✗ Branch 12 not taken.
✗ Branch 13 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_FALSE(same(a, b));
50
2/10
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 15 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 19 not taken.
✗ Branch 20 not taken.
✗ Branch 25 not taken.
✗ Branch 26 not taken.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
2 EXPECT_NE(name(a), name(b));
51
4/14
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 16 taken 1 times.
✗ Branch 17 not taken.
✓ Branch 20 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 29 not taken.
✗ Branch 30 not taken.
✗ Branch 35 not taken.
✗ Branch 36 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
2 EXPECT_NE(area(a), area(b));
52 4 }
53
54 8 TEST(UniqueRef, copy) {
55 // UniqueRef is not copyable because unique_ptr is not copyable.
56
1/10
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
2 EXPECT_FALSE(std::is_copy_constructible<UniqueRef<int>>::value);
57
1/10
✗ Branch 5 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 9 not taken.
✗ Branch 10 not taken.
✗ Branch 15 not taken.
✗ Branch 16 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
2 EXPECT_FALSE(std::is_copy_assignable<UniqueRef<int>>::value);
58 2 }
59
60 8 TEST(UniqueRef, move) {
61 // UniqueRef is moveable because unique_ptr is moveable.
62
1/10
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_TRUE(std::is_move_constructible<UniqueRef<int>>::value);
63
1/10
✗ Branch 3 not taken.
✓ Branch 4 taken 1 times.
✗ Branch 7 not taken.
✗ Branch 8 not taken.
✗ Branch 13 not taken.
✗ Branch 14 not taken.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 22 not taken.
✗ Branch 23 not taken.
2 EXPECT_TRUE(std::is_move_assignable<UniqueRef<int>>::value);
64
65
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 auto a = makeUniqueRef<Verbose<Circle>>("one", 1.0);
66
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 auto b = makeUniqueRef<Verbose<Circle>>("two", 2.0);
67
1/2
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
2 auto c = makeUniqueRef<Verbose<Circle>>("three", 3.0);
68 4 auto d = UniqueRef<Verbose<Circle>>{std::move(a)}; // move constructor
69
70 2 c = std::move(b); // move assignment
71
72 // Moving modifies the reference, not the object.
73
74
4/14
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
2 EXPECT_THAT(name(c), EndsWith("two"));
75
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(c), Not(HasSubstr("three")));
76
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(c), Not(HasSubstr("copy")));
77
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(c), Not(HasSubstr("move")));
78
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(c), Not(HasSubstr("construct")));
79
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(c), Not(HasSubstr("assign")));
80
81
4/14
✓ Branch 4 taken 1 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 15 taken 1 times.
✗ Branch 16 not taken.
✗ Branch 22 not taken.
✓ Branch 23 taken 1 times.
✗ Branch 26 not taken.
✗ Branch 27 not taken.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
2 EXPECT_THAT(name(d), EndsWith("one"));
82
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(d), Not(HasSubstr("copy")));
83
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(d), Not(HasSubstr("move")));
84
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(d), Not(HasSubstr("construct")));
85
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 19 taken 1 times.
✗ Branch 20 not taken.
✗ Branch 28 not taken.
✓ Branch 29 taken 1 times.
✗ Branch 32 not taken.
✗ Branch 33 not taken.
✗ Branch 38 not taken.
✗ Branch 39 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
2 EXPECT_THAT(name(d), Not(HasSubstr("assign")));
86 4 }
87
88 8 TEST(UniqueRef, rebind) {
89
1/2
✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
2 CaptureStdout();
90
4/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 20 not taken.
✓ Branch 21 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
6 auto a = UniqueRef<Shape>(new Verbose<Square>{"square", 3.0});
91 4 auto b = std::move(a); // move reference, not object
92
4/10
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 1 times.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
6 b = UniqueRef<Shape>{new Verbose<Circle>{"circle", 3.0}};
93
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto actual = GetCapturedStdout();
94
3/12
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
✓ Branch 12 taken 1 times.
✗ Branch 13 not taken.
✗ Branch 17 not taken.
✓ Branch 18 taken 1 times.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 31 not taken.
✗ Branch 32 not taken.
2 EXPECT_NE(9.0, area(b));
95
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
2 EXPECT_THAT(actual, Not(HasSubstr("copy")));
96
5/16
✓ Branch 5 taken 1 times.
✗ Branch 6 not taken.
✓ Branch 8 taken 1 times.
✗ Branch 9 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 12 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 15 not taken.
✗ Branch 23 not taken.
✓ Branch 24 taken 1 times.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 37 not taken.
✗ Branch 38 not taken.
2 EXPECT_THAT(actual, Not(HasSubstr("move")));
97
3/6
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✓ Branch 13 taken 1 times.
✗ Branch 14 not taken.
2 std::cout << std::endl << actual << std::endl;
98 4 }
99
100 8 TEST(UniqueRef, swap) {
101
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto a = makeUniqueRef<Verbose<>>("one");
102
1/2
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 auto b = makeUniqueRef<Verbose<>>("two");
103 2 swap(a, b);
104
2/10
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
2 EXPECT_EQ("one", name(b));
105
2/10
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
✗ Branch 10 not taken.
✓ Branch 11 taken 1 times.
✗ Branch 14 not taken.
✗ Branch 15 not taken.
✗ Branch 20 not taken.
✗ Branch 21 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
2 EXPECT_EQ("two", name(a));
106 4 }
107
108 8 TEST(UniqueRef, container) {
109 2 auto container = UniqueContainer<Verbose<>>{};
110
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 container.emplace_back(std::make_unique<Verbose<>>("one"));
111
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 container.emplace_back(std::make_unique<Verbose<>>("two"));
112
2/4
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
✓ Branch 6 taken 1 times.
✗ Branch 7 not taken.
2 container.emplace_back(std::make_unique<Verbose<>>("three"));
113
114
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
6 print(container, "original: ");
115
2/10
✓ Branch 10 taken 1 times.
✗ Branch 11 not taken.
✗ Branch 13 not taken.
✓ Branch 14 taken 1 times.
✗ Branch 17 not taken.
✗ Branch 18 not taken.
✗ Branch 23 not taken.
✗ Branch 24 not taken.
✗ Branch 27 not taken.
✗ Branch 28 not taken.
2 EXPECT_EQ("two", name(container[1]));
116
117 // Moving a container of references
118 // does not move the objects.
119 4 auto container_move = std::move(container);
120
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
6 print(container_move, "move: ");
121 4 }
122
123 // NOLINTEND(*-avoid-magic-numbers)
124