blob: 8d4057cfe4d474a8ead0be4bad40b35224529c38 [file] [log] [blame]
// Copyright (c) 2012 The Chromium 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 "base/memory/weak_ptr.h"
#include <string>
#include <gtest/gtest.h>
#include "base/bind.h"
#include "base/location.h"
#include "base/memory/scoped_ptr.h"
namespace base {
namespace {
struct Base {
std::string member;
};
struct Derived : public Base {};
struct TargetBase {};
struct Target : public TargetBase, public SupportsWeakPtr<Target> {
virtual ~Target() {}
};
struct DerivedTarget : public Target {};
struct Arrow {
WeakPtr<Target> target;
};
struct TargetWithFactory : public Target {
TargetWithFactory() : factory(this) {}
WeakPtrFactory<Target> factory;
};
} // namespace
TEST(WeakPtrFactoryTest, Basic) {
int data;
WeakPtrFactory<int> factory(&data);
WeakPtr<int> ptr = factory.GetWeakPtr();
EXPECT_EQ(&data, ptr.get());
}
TEST(WeakPtrFactoryTest, Comparison) {
int data;
WeakPtrFactory<int> factory(&data);
WeakPtr<int> ptr = factory.GetWeakPtr();
WeakPtr<int> ptr2 = ptr;
EXPECT_EQ(ptr.get(), ptr2.get());
}
TEST(WeakPtrFactoryTest, OutOfScope) {
WeakPtr<int> ptr;
EXPECT_EQ(NULL, ptr.get());
{
int data;
WeakPtrFactory<int> factory(&data);
ptr = factory.GetWeakPtr();
}
EXPECT_EQ(NULL, ptr.get());
}
TEST(WeakPtrFactoryTest, Multiple) {
WeakPtr<int> a, b;
{
int data;
WeakPtrFactory<int> factory(&data);
a = factory.GetWeakPtr();
b = factory.GetWeakPtr();
EXPECT_EQ(&data, a.get());
EXPECT_EQ(&data, b.get());
}
EXPECT_EQ(NULL, a.get());
EXPECT_EQ(NULL, b.get());
}
TEST(WeakPtrFactoryTest, MultipleStaged) {
WeakPtr<int> a;
{
int data;
WeakPtrFactory<int> factory(&data);
a = factory.GetWeakPtr();
{
WeakPtr<int> b = factory.GetWeakPtr();
}
EXPECT_TRUE(NULL != a.get());
}
EXPECT_EQ(NULL, a.get());
}
TEST(WeakPtrFactoryTest, Dereference) {
Base data;
data.member = "123456";
WeakPtrFactory<Base> factory(&data);
WeakPtr<Base> ptr = factory.GetWeakPtr();
EXPECT_EQ(&data, ptr.get());
EXPECT_EQ(data.member, (*ptr).member);
EXPECT_EQ(data.member, ptr->member);
}
TEST(WeakPtrFactoryTest, UpCast) {
Derived data;
WeakPtrFactory<Derived> factory(&data);
WeakPtr<Base> ptr = factory.GetWeakPtr();
ptr = factory.GetWeakPtr();
EXPECT_EQ(ptr.get(), &data);
}
TEST(WeakPtrTest, SupportsWeakPtr) {
Target target;
WeakPtr<Target> ptr = target.AsWeakPtr();
EXPECT_EQ(&target, ptr.get());
}
TEST(WeakPtrTest, DerivedTarget) {
DerivedTarget target;
WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
EXPECT_EQ(&target, ptr.get());
}
TEST(WeakPtrTest, InvalidateWeakPtrs) {
int data;
WeakPtrFactory<int> factory(&data);
WeakPtr<int> ptr = factory.GetWeakPtr();
EXPECT_EQ(&data, ptr.get());
EXPECT_TRUE(factory.HasWeakPtrs());
factory.InvalidateWeakPtrs();
EXPECT_EQ(NULL, ptr.get());
EXPECT_FALSE(factory.HasWeakPtrs());
// Test that the factory can create new weak pointers after a
// InvalidateWeakPtrs call, and they remain valid until the next
// InvalidateWeakPtrs call.
WeakPtr<int> ptr2 = factory.GetWeakPtr();
EXPECT_EQ(&data, ptr2.get());
EXPECT_TRUE(factory.HasWeakPtrs());
factory.InvalidateWeakPtrs();
EXPECT_EQ(NULL, ptr2.get());
EXPECT_FALSE(factory.HasWeakPtrs());
}
TEST(WeakPtrTest, HasWeakPtrs) {
int data;
WeakPtrFactory<int> factory(&data);
{
WeakPtr<int> ptr = factory.GetWeakPtr();
EXPECT_TRUE(factory.HasWeakPtrs());
}
EXPECT_FALSE(factory.HasWeakPtrs());
}
} // namespace base