OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import <Foundation/Foundation.h> | 5 #import <Foundation/Foundation.h> |
6 #include <objc/runtime.h> | 6 #include <objc/runtime.h> |
7 | 7 |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #import "base/memory/scoped_nsobject.h" | 9 #import "base/mac/scoped_nsobject.h" |
10 #import "chrome/common/mac/objc_zombie.h" | 10 #import "chrome/common/mac/objc_zombie.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 #include "testing/platform_test.h" | 12 #include "testing/platform_test.h" |
13 | 13 |
14 @interface ZombieCxxDestructTest : NSObject | 14 @interface ZombieCxxDestructTest : NSObject |
15 { | 15 { |
16 scoped_nsobject<id> aRef_; | 16 base::scoped_nsobject<id> aRef_; |
17 } | 17 } |
18 - (id)initWith:(id)anObject; | 18 - (id)initWith:(id)anObject; |
19 @end | 19 @end |
20 | 20 |
21 @implementation ZombieCxxDestructTest | 21 @implementation ZombieCxxDestructTest |
22 - (id)initWith:(id)anObject { | 22 - (id)initWith:(id)anObject { |
23 self = [super init]; | 23 self = [super init]; |
24 if (self) { | 24 if (self) { |
25 aRef_.reset([anObject retain]); | 25 aRef_.reset([anObject retain]); |
26 } | 26 } |
(...skipping 20 matching lines...) Expand all Loading... |
47 | 47 |
48 @end | 48 @end |
49 | 49 |
50 namespace { | 50 namespace { |
51 | 51 |
52 // Verify that the C++ destructors run when the last reference to the | 52 // Verify that the C++ destructors run when the last reference to the |
53 // object is released. | 53 // object is released. |
54 // NOTE(shess): To test the negative, comment out the |g_objectDestruct()| | 54 // NOTE(shess): To test the negative, comment out the |g_objectDestruct()| |
55 // call in |ZombieDealloc()|. | 55 // call in |ZombieDealloc()|. |
56 TEST(ObjcZombieTest, CxxDestructors) { | 56 TEST(ObjcZombieTest, CxxDestructors) { |
57 scoped_nsobject<id> anObject([[NSObject alloc] init]); | 57 base::scoped_nsobject<id> anObject([[NSObject alloc] init]); |
58 EXPECT_EQ(1u, [anObject retainCount]); | 58 EXPECT_EQ(1u, [anObject retainCount]); |
59 | 59 |
60 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100)); | 60 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100)); |
61 | 61 |
62 scoped_nsobject<ZombieCxxDestructTest> soonInfected( | 62 base::scoped_nsobject<ZombieCxxDestructTest> soonInfected( |
63 [[ZombieCxxDestructTest alloc] initWith:anObject]); | 63 [[ZombieCxxDestructTest alloc] initWith:anObject]); |
64 EXPECT_EQ(2u, [anObject retainCount]); | 64 EXPECT_EQ(2u, [anObject retainCount]); |
65 | 65 |
66 // When |soonInfected| becomes a zombie, the C++ destructors should | 66 // When |soonInfected| becomes a zombie, the C++ destructors should |
67 // run and release a reference to |anObject|. | 67 // run and release a reference to |anObject|. |
68 soonInfected.reset(); | 68 soonInfected.reset(); |
69 EXPECT_EQ(1u, [anObject retainCount]); | 69 EXPECT_EQ(1u, [anObject retainCount]); |
70 | 70 |
71 // The local reference should remain (C++ destructors aren't re-run). | 71 // The local reference should remain (C++ destructors aren't re-run). |
72 ObjcEvilDoers::ZombieDisable(); | 72 ObjcEvilDoers::ZombieDisable(); |
73 EXPECT_EQ(1u, [anObject retainCount]); | 73 EXPECT_EQ(1u, [anObject retainCount]); |
74 } | 74 } |
75 | 75 |
76 // Verify that the associated objects are released when the object is | 76 // Verify that the associated objects are released when the object is |
77 // released. | 77 // released. |
78 TEST(ObjcZombieTest, AssociatedObjectsReleased) { | 78 TEST(ObjcZombieTest, AssociatedObjectsReleased) { |
79 scoped_nsobject<id> anObject([[NSObject alloc] init]); | 79 base::scoped_nsobject<id> anObject([[NSObject alloc] init]); |
80 EXPECT_EQ(1u, [anObject retainCount]); | 80 EXPECT_EQ(1u, [anObject retainCount]); |
81 | 81 |
82 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100)); | 82 ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100)); |
83 | 83 |
84 scoped_nsobject<ZombieAssociatedObjectTest> soonInfected( | 84 base::scoped_nsobject<ZombieAssociatedObjectTest> soonInfected( |
85 [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]); | 85 [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]); |
86 EXPECT_EQ(2u, [anObject retainCount]); | 86 EXPECT_EQ(2u, [anObject retainCount]); |
87 | 87 |
88 // When |soonInfected| becomes a zombie, the associated object | 88 // When |soonInfected| becomes a zombie, the associated object |
89 // should be released. | 89 // should be released. |
90 soonInfected.reset(); | 90 soonInfected.reset(); |
91 EXPECT_EQ(1u, [anObject retainCount]); | 91 EXPECT_EQ(1u, [anObject retainCount]); |
92 | 92 |
93 // The local reference should remain (associated objects not re-released). | 93 // The local reference should remain (associated objects not re-released). |
94 ObjcEvilDoers::ZombieDisable(); | 94 ObjcEvilDoers::ZombieDisable(); |
95 EXPECT_EQ(1u, [anObject retainCount]); | 95 EXPECT_EQ(1u, [anObject retainCount]); |
96 } | 96 } |
97 | 97 |
98 } // namespace | 98 } // namespace |
OLD | NEW |