blob: e24a0b27cb86dd3b01509d2c0533de88a7442ab3 [file] [log] [blame]
// Copyright 2017 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "core/fxcrt/unowned_ptr.h"
#include <utility>
#include "testing/gtest/include/gtest/gtest.h"
namespace fxcrt {
namespace {
class Clink {
public:
UnownedPtr<Clink> next_ = nullptr;
};
void DeleteDangling() {
auto ptr2 = std::make_unique<Clink>();
{
auto ptr1 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
}
}
void ResetDangling() {
auto ptr2 = std::make_unique<Clink>();
{
auto ptr1 = std::make_unique<Clink>();
ptr2->next_.Reset(ptr1.get());
}
ptr2->next_.Reset();
}
void AssignDangling() {
auto ptr2 = std::make_unique<Clink>();
{
auto ptr1 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
}
ptr2->next_ = nullptr;
}
void ReleaseDangling() {
auto ptr2 = std::make_unique<Clink>();
{
auto ptr1 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
}
ptr2->next_.Release();
}
} // namespace
TEST(UnownedPtr, PtrOk) {
auto ptr1 = std::make_unique<Clink>();
{
auto ptr2 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
}
}
TEST(UnownedPtr, PtrNotOk) {
#if defined(ADDRESS_SANITIZER)
EXPECT_DEATH(DeleteDangling(), "");
#else
DeleteDangling();
#endif
}
TEST(UnownedPtr, ResetOk) {
auto ptr1 = std::make_unique<Clink>();
{
auto ptr2 = std::make_unique<Clink>();
ptr2->next_.Reset(ptr1.get());
ptr2->next_.Reset(nullptr);
}
}
TEST(UnownedPtr, ResetNotOk) {
#if defined(ADDRESS_SANITIZER)
EXPECT_DEATH(ResetDangling(), "");
#else
ResetDangling();
#endif
}
TEST(UnownedPtr, AssignOk) {
auto ptr1 = std::make_unique<Clink>();
{
auto ptr2 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
ptr2->next_ = nullptr;
}
}
TEST(UnownedPtr, AssignNotOk) {
#if defined(ADDRESS_SANITIZER)
EXPECT_DEATH(AssignDangling(), "");
#else
AssignDangling();
#endif
}
TEST(UnownedPtr, ReleaseOk) {
auto ptr2 = std::make_unique<Clink>();
{
auto ptr1 = std::make_unique<Clink>();
ptr2->next_ = ptr1.get();
ptr2->next_.Release();
}
}
TEST(UnownedPtr, MoveCtorOk) {
UnownedPtr<Clink> outer;
{
auto owned = std::make_unique<Clink>();
outer = owned.get();
UnownedPtr<Clink> inner(std::move(outer));
EXPECT_EQ(nullptr, outer.Get());
}
}
TEST(UnownedPtr, MoveAssignOk) {
UnownedPtr<Clink> outer;
{
auto owned = std::make_unique<Clink>();
outer = owned.get();
UnownedPtr<Clink> inner;
inner = std::move(outer);
EXPECT_EQ(nullptr, outer.Get());
}
}
TEST(UnownedPtr, ReleaseNotOk) {
#if defined(ADDRESS_SANITIZER)
EXPECT_DEATH(ReleaseDangling(), "");
#else
ReleaseDangling();
#endif
}
TEST(UnownedPtr, OperatorEQ) {
int foo;
UnownedPtr<int> ptr1;
EXPECT_TRUE(ptr1 == ptr1);
UnownedPtr<int> ptr2;
EXPECT_TRUE(ptr1 == ptr2);
UnownedPtr<int> ptr3(&foo);
EXPECT_TRUE(&foo == ptr3);
EXPECT_TRUE(ptr3 == &foo);
EXPECT_FALSE(ptr1 == ptr3);
ptr1 = &foo;
EXPECT_TRUE(ptr1 == ptr3);
}
TEST(UnownedPtr, OperatorNE) {
int foo;
UnownedPtr<int> ptr1;
EXPECT_FALSE(ptr1 != ptr1);
UnownedPtr<int> ptr2;
EXPECT_FALSE(ptr1 != ptr2);
UnownedPtr<int> ptr3(&foo);
EXPECT_FALSE(&foo != ptr3);
EXPECT_FALSE(ptr3 != &foo);
EXPECT_TRUE(ptr1 != ptr3);
ptr1 = &foo;
EXPECT_FALSE(ptr1 != ptr3);
}
TEST(UnownedPtr, OperatorLT) {
int foos[2];
UnownedPtr<int> ptr1(&foos[0]);
UnownedPtr<int> ptr2(&foos[1]);
EXPECT_FALSE(ptr1 < ptr1);
EXPECT_TRUE(ptr1 < ptr2);
EXPECT_FALSE(ptr2 < ptr1);
}
} // namespace fxcrt