summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/api/scoped_refptr_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/api/scoped_refptr_unittest.cc')
-rw-r--r--third_party/libwebrtc/api/scoped_refptr_unittest.cc111
1 files changed, 111 insertions, 0 deletions
diff --git a/third_party/libwebrtc/api/scoped_refptr_unittest.cc b/third_party/libwebrtc/api/scoped_refptr_unittest.cc
new file mode 100644
index 0000000000..22b61209cd
--- /dev/null
+++ b/third_party/libwebrtc/api/scoped_refptr_unittest.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2019 The WebRTC Project Authors. All rights reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "api/scoped_refptr.h"
+
+#include <utility>
+#include <vector>
+
+#include "test/gtest.h"
+
+namespace rtc {
+namespace {
+
+struct FunctionsCalled {
+ int addref = 0;
+ int release = 0;
+};
+
+class ScopedRefCounted {
+ public:
+ explicit ScopedRefCounted(FunctionsCalled* called) : called_(*called) {}
+ ScopedRefCounted(const ScopedRefCounted&) = delete;
+ ScopedRefCounted& operator=(const ScopedRefCounted&) = delete;
+
+ void AddRef() {
+ ++called_.addref;
+ ++ref_count_;
+ }
+ void Release() {
+ ++called_.release;
+ if (0 == --ref_count_)
+ delete this;
+ }
+
+ private:
+ ~ScopedRefCounted() = default;
+
+ FunctionsCalled& called_;
+ int ref_count_ = 0;
+};
+
+TEST(ScopedRefptrTest, IsCopyConstructable) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ scoped_refptr<ScopedRefCounted> another_ptr = ptr;
+
+ EXPECT_TRUE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 2);
+}
+
+TEST(ScopedRefptrTest, IsCopyAssignable) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> another_ptr;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ another_ptr = ptr;
+
+ EXPECT_TRUE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 2);
+}
+
+TEST(ScopedRefptrTest, IsMoveConstructableWithoutExtraAddRefRelease) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ scoped_refptr<ScopedRefCounted> another_ptr = std::move(ptr);
+
+ EXPECT_FALSE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 1);
+ EXPECT_EQ(called.release, 0);
+}
+
+TEST(ScopedRefptrTest, IsMoveAssignableWithoutExtraAddRefRelease) {
+ FunctionsCalled called;
+ scoped_refptr<ScopedRefCounted> another_ptr;
+ scoped_refptr<ScopedRefCounted> ptr(new ScopedRefCounted(&called));
+ another_ptr = std::move(ptr);
+
+ EXPECT_FALSE(ptr);
+ EXPECT_TRUE(another_ptr);
+ EXPECT_EQ(called.addref, 1);
+ EXPECT_EQ(called.release, 0);
+}
+
+TEST(ScopedRefptrTest, MovableDuringVectorReallocation) {
+ static_assert(
+ std::is_nothrow_move_constructible<scoped_refptr<ScopedRefCounted>>(),
+ "");
+ // Test below describes a scenario where it is helpful for move constructor
+ // to be noexcept.
+ FunctionsCalled called;
+ std::vector<scoped_refptr<ScopedRefCounted>> ptrs;
+ ptrs.reserve(1);
+ // Insert more elements than reserved to provoke reallocation.
+ ptrs.emplace_back(new ScopedRefCounted(&called));
+ ptrs.emplace_back(new ScopedRefCounted(&called));
+
+ EXPECT_EQ(called.addref, 2);
+ EXPECT_EQ(called.release, 0);
+}
+
+} // namespace
+} // namespace rtc