1cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// Use of this source code is governed by a BSD-style license that can be
3cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka// found in the LICENSE file.
4cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
5cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/memory/weak_ptr.h"
6cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
7cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include <string>
8cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
98750b279d610fb21d10a205e28e081832ed837eeVitaly Buka#include <gtest/gtest.h>
108750b279d610fb21d10a205e28e081832ed837eeVitaly Buka
11cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/bind.h"
12cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/location.h"
13cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka#include "base/memory/scoped_ptr.h"
14cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
15cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukanamespace base {
16cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukanamespace {
17cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
18cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct Base {
19cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  std::string member;
20cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka};
21cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct Derived : public Base {};
22cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
23cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct TargetBase {};
24cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct Target : public TargetBase, public SupportsWeakPtr<Target> {
25cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  virtual ~Target() {}
26cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka};
27cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct DerivedTarget : public Target {};
28cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct Arrow {
29cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<Target> target;
30cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka};
31cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Bukastruct TargetWithFactory : public Target {
32cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  TargetWithFactory() : factory(this) {}
33cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<Target> factory;
34cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka};
35cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
36cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}  // namespace
37cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
38cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, Basic) {
39cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  int data;
40cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<int> factory(&data);
41cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr = factory.GetWeakPtr();
42cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&data, ptr.get());
43cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
44cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
45cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, Comparison) {
46cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  int data;
47cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<int> factory(&data);
48cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr = factory.GetWeakPtr();
49cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr2 = ptr;
50cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(ptr.get(), ptr2.get());
51cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
52cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
53cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, OutOfScope) {
54cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr;
55cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, ptr.get());
56cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  {
57cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    int data;
58cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    WeakPtrFactory<int> factory(&data);
59cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    ptr = factory.GetWeakPtr();
60cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
61cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, ptr.get());
62cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
63cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
64cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, Multiple) {
65cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> a, b;
66cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  {
67cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    int data;
68cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    WeakPtrFactory<int> factory(&data);
69cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    a = factory.GetWeakPtr();
70cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    b = factory.GetWeakPtr();
71cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    EXPECT_EQ(&data, a.get());
72cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    EXPECT_EQ(&data, b.get());
73cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
74cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, a.get());
75cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, b.get());
76cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
77cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
78cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, MultipleStaged) {
79cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> a;
80cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  {
81cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    int data;
82cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    WeakPtrFactory<int> factory(&data);
83cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    a = factory.GetWeakPtr();
84cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    {
85cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka      WeakPtr<int> b = factory.GetWeakPtr();
86cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    }
87cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    EXPECT_TRUE(NULL != a.get());
88cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
89cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, a.get());
90cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
91cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
92cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, Dereference) {
93cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Base data;
94cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  data.member = "123456";
95cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<Base> factory(&data);
96cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<Base> ptr = factory.GetWeakPtr();
97cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&data, ptr.get());
98cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(data.member, (*ptr).member);
99cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(data.member, ptr->member);
100cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
101cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
102cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrFactoryTest, UpCast) {
103cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Derived data;
104cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<Derived> factory(&data);
105cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<Base> ptr = factory.GetWeakPtr();
106cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  ptr = factory.GetWeakPtr();
107cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(ptr.get(), &data);
108cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
109cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
110cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrTest, SupportsWeakPtr) {
111cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  Target target;
112cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<Target> ptr = target.AsWeakPtr();
113cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&target, ptr.get());
114cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
115cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
116cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrTest, DerivedTarget) {
117cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  DerivedTarget target;
118cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<DerivedTarget> ptr = AsWeakPtr(&target);
119cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&target, ptr.get());
120cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
121cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
122cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrTest, InvalidateWeakPtrs) {
123cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  int data;
124cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<int> factory(&data);
125cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr = factory.GetWeakPtr();
126cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&data, ptr.get());
127cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_TRUE(factory.HasWeakPtrs());
128cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  factory.InvalidateWeakPtrs();
129cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, ptr.get());
130cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_FALSE(factory.HasWeakPtrs());
131cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
132cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // Test that the factory can create new weak pointers after a
133cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // InvalidateWeakPtrs call, and they remain valid until the next
134cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  // InvalidateWeakPtrs call.
135cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtr<int> ptr2 = factory.GetWeakPtr();
136cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(&data, ptr2.get());
137cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_TRUE(factory.HasWeakPtrs());
138cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  factory.InvalidateWeakPtrs();
139cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_EQ(NULL, ptr2.get());
140cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_FALSE(factory.HasWeakPtrs());
141cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
142cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
143cbed206b598349b26cd060eebb7e2d3b70305044Vitaly BukaTEST(WeakPtrTest, HasWeakPtrs) {
144cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  int data;
145cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  WeakPtrFactory<int> factory(&data);
146cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  {
147cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    WeakPtr<int> ptr = factory.GetWeakPtr();
148cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka    EXPECT_TRUE(factory.HasWeakPtrs());
149cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  }
150cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka  EXPECT_FALSE(factory.HasWeakPtrs());
151cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}
152cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka
153cbed206b598349b26cd060eebb7e2d3b70305044Vitaly Buka}  // namespace base
154