Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3170)

Unified Diff: chrome/browser/ui/cocoa/objc_zombie_unittest.mm

Issue 7084017: [Mac] Use object_destructInstance() if available. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Avi grammar nits. Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/ui/cocoa/objc_zombie.mm ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/ui/cocoa/objc_zombie_unittest.mm
diff --git a/chrome/browser/ui/cocoa/objc_zombie_unittest.mm b/chrome/browser/ui/cocoa/objc_zombie_unittest.mm
index 69f6ea0315806e2c83df6356598b322e2c3103f7..1cadf4a7888e7565dcc193dca226a393aabb9664 100644
--- a/chrome/browser/ui/cocoa/objc_zombie_unittest.mm
+++ b/chrome/browser/ui/cocoa/objc_zombie_unittest.mm
@@ -3,12 +3,28 @@
// found in the LICENSE file.
#import <Cocoa/Cocoa.h>
+#include <dlfcn.h>
+#include "base/logging.h"
#import "base/memory/scoped_nsobject.h"
#import "chrome/browser/ui/cocoa/objc_zombie.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
+namespace {
+
+// Dynamically look up |objc_setAssociatedObject()|, which isn't
+// available until the 10.6 SDK.
+
+typedef void objc_setAssociatedObjectFn(id object, void *key, id value,
+ int policy);
+objc_setAssociatedObjectFn* LookupSetAssociatedObjectFn() {
+ return reinterpret_cast<objc_setAssociatedObjectFn*>(
+ dlsym(RTLD_DEFAULT, "objc_setAssociatedObject"));
+}
+
+} // namespace
+
@interface ZombieCxxDestructTest : NSObject
{
scoped_nsobject<id> aRef_;
@@ -26,13 +42,45 @@
}
@end
+@interface ZombieAssociatedObjectTest : NSObject
++ (BOOL)supportsAssociatedObjects;
+- (id)initWithAssociatedObject:(id)anObject;
+@end
+
+@implementation ZombieAssociatedObjectTest
+
++ (BOOL)supportsAssociatedObjects {
+ if (LookupSetAssociatedObjectFn())
+ return YES;
+ return NO;
+}
+
+- (id)initWithAssociatedObject:(id)anObject {
+ self = [super init];
+ if (self) {
+ objc_setAssociatedObjectFn* fn = LookupSetAssociatedObjectFn();
+ if (fn) {
+ // Cribbed from 10.6 <objc/runtime.h>.
+ static const int kObjcAssociationRetain = 01401;
+
+ // The address of the variable itself is the unique key, the
+ // contents don't matter.
+ static char kAssociatedObjectKey = 'x';
+
+ (*fn)(self, &kAssociatedObjectKey, anObject, kObjcAssociationRetain);
+ }
+ }
+ return self;
+}
+
+@end
+
namespace {
// Verify that the C++ destructors run when the last reference to the
-// object is released. Unfortunately, testing the negative requires
-// commenting out the |object_cxxDestruct()| call in
-// |ZombieDealloc()|.
-
+// object is released.
+// NOTE(shess): To test the negative, comment out the |g_objectDestruct()|
+// call in |ZombieDealloc()|.
TEST(ObjcZombieTest, CxxDestructors) {
scoped_nsobject<id> anObject([[NSObject alloc] init]);
EXPECT_EQ(1u, [anObject retainCount]);
@@ -53,4 +101,34 @@ TEST(ObjcZombieTest, CxxDestructors) {
EXPECT_EQ(1u, [anObject retainCount]);
}
+// Verify that the associated objects are released when the object is
+// released.
+// NOTE(shess): To test the negative, hardcode |g_objectDestruct| to
+// the 10.5 version in |ZombieInit()|, and run this test on 10.6.
+TEST(ObjcZombieTest, AssociatedObjectsReleased) {
+ if (![ZombieAssociatedObjectTest supportsAssociatedObjects]) {
+ LOG(ERROR)
+ << "ObjcZombieTest.AssociatedObjectsReleased not supported on 10.5";
+ return;
+ }
+
+ scoped_nsobject<id> anObject([[NSObject alloc] init]);
+ EXPECT_EQ(1u, [anObject retainCount]);
+
+ ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100));
+
+ scoped_nsobject<ZombieAssociatedObjectTest> soonInfected(
+ [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]);
+ EXPECT_EQ(2u, [anObject retainCount]);
+
+ // When |soonInfected| becomes a zombie, the associated object
+ // should be released.
+ soonInfected.reset();
+ EXPECT_EQ(1u, [anObject retainCount]);
+
+ // The local reference should remain (associated objects not re-released).
+ ObjcEvilDoers::ZombieDisable();
+ EXPECT_EQ(1u, [anObject retainCount]);
+}
+
} // namespace
« no previous file with comments | « chrome/browser/ui/cocoa/objc_zombie.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698