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

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: Per-runtime initialization, unit test, misc. 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
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..f997c45fdf476093738633a4707b99e2c9e813ab 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 lookup |objc_setAssociatedObject()|, which isn't
Mark Mentovai 2011/06/07 21:42:57 look up
Scott Hess - ex-Googler 2011/06/07 23:48:21 Done.
+// 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,18 +42,54 @@
}
@end
+@interface ZombieAssociatedObjectTest : NSObject
+{
Mark Mentovai 2011/06/07 21:42:57 You don’t need the { } for an instance variable-fr
Scott Hess - ex-Googler 2011/06/07 23:48:21 Done.
+}
++ (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]);
- ASSERT_TRUE(ObjcEvilDoers::ZombieEnable(YES, 100));
+ ASSERT_TRUE(
+ ObjcEvilDoers::ZombieEnable(ObjcEvilDoers::RUNTIME_GUESS, YES, 100));
scoped_nsobject<ZombieCxxDestructTest> soonInfected(
[[ZombieCxxDestructTest alloc] initWith:anObject]);
@@ -53,4 +105,35 @@ 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, enable zombies with
+// |RUNTIME_10_5|, and run this test in isolation 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(ObjcEvilDoers::RUNTIME_GUESS, YES, 100));
+
+ scoped_nsobject<ZombieAssociatedObjectTest> soonInfected(
+ [[ZombieAssociatedObjectTest alloc] initWithAssociatedObject:anObject]);
+ EXPECT_EQ(2u, [anObject retainCount]);
+
+ // When |soonInfected| becomes a zombie, the associated object
Mark Mentovai 2011/06/07 21:42:57 Good test.
+ // 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

Powered by Google App Engine
This is Rietveld 408576698