| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #import <Foundation/Foundation.h> | |
| 6 | |
| 7 #import "base/mac/objc_property_releaser.h" | |
| 8 #import "base/mac/scoped_nsautorelease_pool.h" | |
| 9 #include "testing/gtest/include/gtest/gtest.h" | |
| 10 | |
| 11 // "When I'm alone, I count myself." | |
| 12 // --Count von Count, http://www.youtube.com/watch?v=FKzszqa9WA4 | |
| 13 | |
| 14 namespace { | |
| 15 | |
| 16 // The number of CountVonCounts outstanding. | |
| 17 int ah_ah_ah; | |
| 18 | |
| 19 // NumberHolder exists to exercise the property attribute string parser by | |
| 20 // providing a named struct and an anonymous union. | |
| 21 struct NumberHolder { | |
| 22 union { | |
| 23 long long sixty_four; | |
| 24 int thirty_two; | |
| 25 short sixteen; | |
| 26 char eight; | |
| 27 } what; | |
| 28 enum { | |
| 29 SIXTY_FOUR, | |
| 30 THIRTY_TWO, | |
| 31 SIXTEEN, | |
| 32 EIGHT | |
| 33 } how; | |
| 34 }; | |
| 35 | |
| 36 } // namespace | |
| 37 | |
| 38 @interface CountVonCount : NSObject<NSCopying> | |
| 39 | |
| 40 + (CountVonCount*)countVonCount; | |
| 41 | |
| 42 @end // @interface CountVonCount | |
| 43 | |
| 44 @implementation CountVonCount | |
| 45 | |
| 46 + (CountVonCount*)countVonCount { | |
| 47 return [[[CountVonCount alloc] init] autorelease]; | |
| 48 } | |
| 49 | |
| 50 - (id)init { | |
| 51 ++ah_ah_ah; | |
| 52 return [super init]; | |
| 53 } | |
| 54 | |
| 55 - (void)dealloc { | |
| 56 --ah_ah_ah; | |
| 57 [super dealloc]; | |
| 58 } | |
| 59 | |
| 60 - (id)copyWithZone:(NSZone*)zone { | |
| 61 return [[CountVonCount allocWithZone:zone] init]; | |
| 62 } | |
| 63 | |
| 64 @end // @implementation CountVonCount | |
| 65 | |
| 66 @interface ObjCPropertyTestBase : NSObject { | |
| 67 @private | |
| 68 CountVonCount* baseCvcRetain_; | |
| 69 CountVonCount* baseCvcCopy_; | |
| 70 CountVonCount* baseCvcAssign_; | |
| 71 CountVonCount* baseCvcNotProperty_; | |
| 72 CountVonCount* baseCvcNil_; | |
| 73 CountVonCount* baseCvcCustom_; | |
| 74 int baseInt_; | |
| 75 double baseDouble_; | |
| 76 void* basePointer_; | |
| 77 NumberHolder baseStruct_; | |
| 78 | |
| 79 base::mac::ObjCPropertyReleaser propertyReleaser_ObjCPropertyTestBase_; | |
| 80 } | |
| 81 | |
| 82 @property(retain, nonatomic) CountVonCount* baseCvcRetain; | |
| 83 @property(copy, nonatomic) CountVonCount* baseCvcCopy; | |
| 84 @property(assign, nonatomic) CountVonCount* baseCvcAssign; | |
| 85 @property(retain, nonatomic) CountVonCount* baseCvcNil; | |
| 86 @property(retain, nonatomic, getter=baseCustom, setter=setBaseCustom:) | |
| 87 CountVonCount* baseCvcCustom; | |
| 88 @property(retain, nonatomic) CountVonCount* baseCvcDynamic; | |
| 89 @property(assign, nonatomic) int baseInt; | |
| 90 @property(assign, nonatomic) double baseDouble; | |
| 91 @property(assign, nonatomic) void* basePointer; | |
| 92 @property(assign, nonatomic) NumberHolder baseStruct; | |
| 93 | |
| 94 - (void)setBaseCvcNotProperty:(CountVonCount*)cvc; | |
| 95 | |
| 96 @end // @interface ObjCPropertyTestBase | |
| 97 | |
| 98 @implementation ObjCPropertyTestBase | |
| 99 | |
| 100 @synthesize baseCvcRetain = baseCvcRetain_; | |
| 101 @synthesize baseCvcCopy = baseCvcCopy_; | |
| 102 @synthesize baseCvcAssign = baseCvcAssign_; | |
| 103 @synthesize baseCvcNil = baseCvcNil_; | |
| 104 @synthesize baseCvcCustom = baseCvcCustom_; | |
| 105 @dynamic baseCvcDynamic; | |
| 106 @synthesize baseInt = baseInt_; | |
| 107 @synthesize baseDouble = baseDouble_; | |
| 108 @synthesize basePointer = basePointer_; | |
| 109 @synthesize baseStruct = baseStruct_; | |
| 110 | |
| 111 - (id)init { | |
| 112 if ((self = [super init])) { | |
| 113 propertyReleaser_ObjCPropertyTestBase_.Init( | |
| 114 self, [ObjCPropertyTestBase class]); | |
| 115 } | |
| 116 return self; | |
| 117 } | |
| 118 | |
| 119 - (void)dealloc { | |
| 120 [baseCvcNotProperty_ release]; | |
| 121 [super dealloc]; | |
| 122 } | |
| 123 | |
| 124 - (void)setBaseCvcNotProperty:(CountVonCount*)cvc { | |
| 125 if (cvc != baseCvcNotProperty_) { | |
| 126 [baseCvcNotProperty_ release]; | |
| 127 baseCvcNotProperty_ = [cvc retain]; | |
| 128 } | |
| 129 } | |
| 130 | |
| 131 @end // @implementation ObjCPropertyTestBase | |
| 132 | |
| 133 @protocol ObjCPropertyTestProtocol | |
| 134 | |
| 135 @property(retain, nonatomic) CountVonCount* protoCvcRetain; | |
| 136 @property(copy, nonatomic) CountVonCount* protoCvcCopy; | |
| 137 @property(assign, nonatomic) CountVonCount* protoCvcAssign; | |
| 138 @property(retain, nonatomic) CountVonCount* protoCvcNil; | |
| 139 @property(retain, nonatomic, getter=protoCustom, setter=setProtoCustom:) | |
| 140 CountVonCount* protoCvcCustom; | |
| 141 @property(retain, nonatomic) CountVonCount* protoCvcDynamic; | |
| 142 @property(assign, nonatomic) int protoInt; | |
| 143 @property(assign, nonatomic) double protoDouble; | |
| 144 @property(assign, nonatomic) void* protoPointer; | |
| 145 @property(assign, nonatomic) NumberHolder protoStruct; | |
| 146 | |
| 147 @end // @protocol ObjCPropertyTestProtocol | |
| 148 | |
| 149 @interface ObjCPropertyTestDerived | |
| 150 : ObjCPropertyTestBase<ObjCPropertyTestProtocol> { | |
| 151 @private | |
| 152 CountVonCount* derivedCvcRetain_; | |
| 153 CountVonCount* derivedCvcCopy_; | |
| 154 CountVonCount* derivedCvcAssign_; | |
| 155 CountVonCount* derivedCvcNotProperty_; | |
| 156 CountVonCount* derivedCvcNil_; | |
| 157 CountVonCount* derivedCvcCustom_; | |
| 158 int derivedInt_; | |
| 159 double derivedDouble_; | |
| 160 void* derivedPointer_; | |
| 161 NumberHolder derivedStruct_; | |
| 162 | |
| 163 CountVonCount* protoCvcRetain_; | |
| 164 CountVonCount* protoCvcCopy_; | |
| 165 CountVonCount* protoCvcAssign_; | |
| 166 CountVonCount* protoCvcNil_; | |
| 167 CountVonCount* protoCvcCustom_; | |
| 168 int protoInt_; | |
| 169 double protoDouble_; | |
| 170 void* protoPointer_; | |
| 171 NumberHolder protoStruct_; | |
| 172 | |
| 173 base::mac::ObjCPropertyReleaser propertyReleaser_ObjCPropertyTestDerived_; | |
| 174 } | |
| 175 | |
| 176 @property(retain, nonatomic) CountVonCount* derivedCvcRetain; | |
| 177 @property(copy, nonatomic) CountVonCount* derivedCvcCopy; | |
| 178 @property(assign, nonatomic) CountVonCount* derivedCvcAssign; | |
| 179 @property(retain, nonatomic) CountVonCount* derivedCvcNil; | |
| 180 @property(retain, nonatomic, getter=derivedCustom, setter=setDerivedCustom:) | |
| 181 CountVonCount* derivedCvcCustom; | |
| 182 @property(retain, nonatomic) CountVonCount* derivedCvcDynamic; | |
| 183 @property(assign, nonatomic) int derivedInt; | |
| 184 @property(assign, nonatomic) double derivedDouble; | |
| 185 @property(assign, nonatomic) void* derivedPointer; | |
| 186 @property(assign, nonatomic) NumberHolder derivedStruct; | |
| 187 | |
| 188 - (void)setDerivedCvcNotProperty:(CountVonCount*)cvc; | |
| 189 | |
| 190 @end // @interface ObjCPropertyTestDerived | |
| 191 | |
| 192 @implementation ObjCPropertyTestDerived | |
| 193 | |
| 194 @synthesize derivedCvcRetain = derivedCvcRetain_; | |
| 195 @synthesize derivedCvcCopy = derivedCvcCopy_; | |
| 196 @synthesize derivedCvcAssign = derivedCvcAssign_; | |
| 197 @synthesize derivedCvcNil = derivedCvcNil_; | |
| 198 @synthesize derivedCvcCustom = derivedCvcCustom_; | |
| 199 @dynamic derivedCvcDynamic; | |
| 200 @synthesize derivedInt = derivedInt_; | |
| 201 @synthesize derivedDouble = derivedDouble_; | |
| 202 @synthesize derivedPointer = derivedPointer_; | |
| 203 @synthesize derivedStruct = derivedStruct_; | |
| 204 | |
| 205 @synthesize protoCvcRetain = protoCvcRetain_; | |
| 206 @synthesize protoCvcCopy = protoCvcCopy_; | |
| 207 @synthesize protoCvcAssign = protoCvcAssign_; | |
| 208 @synthesize protoCvcNil = protoCvcNil_; | |
| 209 @synthesize protoCvcCustom = protoCvcCustom_; | |
| 210 @dynamic protoCvcDynamic; | |
| 211 @synthesize protoInt = protoInt_; | |
| 212 @synthesize protoDouble = protoDouble_; | |
| 213 @synthesize protoPointer = protoPointer_; | |
| 214 @synthesize protoStruct = protoStruct_; | |
| 215 | |
| 216 - (id)init { | |
| 217 if ((self = [super init])) { | |
| 218 propertyReleaser_ObjCPropertyTestDerived_.Init( | |
| 219 self, [ObjCPropertyTestDerived class]); | |
| 220 } | |
| 221 return self; | |
| 222 } | |
| 223 | |
| 224 - (void)dealloc { | |
| 225 [derivedCvcNotProperty_ release]; | |
| 226 [super dealloc]; | |
| 227 } | |
| 228 | |
| 229 - (void)setDerivedCvcNotProperty:(CountVonCount*)cvc { | |
| 230 if (cvc != derivedCvcNotProperty_) { | |
| 231 [derivedCvcNotProperty_ release]; | |
| 232 derivedCvcNotProperty_ = [cvc retain]; | |
| 233 } | |
| 234 } | |
| 235 | |
| 236 @end // @implementation ObjCPropertyTestDerived | |
| 237 | |
| 238 namespace { | |
| 239 | |
| 240 TEST(ObjCPropertyReleaserTest, SesameStreet) { | |
| 241 ObjCPropertyTestDerived* test_object = [[ObjCPropertyTestDerived alloc] init]; | |
| 242 | |
| 243 // Assure a clean slate. | |
| 244 EXPECT_EQ(0, ah_ah_ah); | |
| 245 EXPECT_EQ(1U, [test_object retainCount]); | |
| 246 | |
| 247 CountVonCount* baseAssign = [[CountVonCount alloc] init]; | |
| 248 CountVonCount* derivedAssign = [[CountVonCount alloc] init]; | |
| 249 CountVonCount* protoAssign = [[CountVonCount alloc] init]; | |
| 250 | |
| 251 // Make sure that worked before things get more involved. | |
| 252 EXPECT_EQ(3, ah_ah_ah); | |
| 253 | |
| 254 { | |
| 255 base::mac::ScopedNSAutoreleasePool pool; | |
| 256 | |
| 257 test_object.baseCvcRetain = [CountVonCount countVonCount]; | |
| 258 test_object.baseCvcCopy = [CountVonCount countVonCount]; | |
| 259 test_object.baseCvcAssign = baseAssign; | |
| 260 test_object.baseCvcCustom = [CountVonCount countVonCount]; | |
| 261 [test_object setBaseCvcNotProperty:[CountVonCount countVonCount]]; | |
| 262 | |
| 263 // That added 4 objects, plus 1 more that was copied. | |
| 264 EXPECT_EQ(8, ah_ah_ah); | |
| 265 | |
| 266 test_object.derivedCvcRetain = [CountVonCount countVonCount]; | |
| 267 test_object.derivedCvcCopy = [CountVonCount countVonCount]; | |
| 268 test_object.derivedCvcAssign = derivedAssign; | |
| 269 test_object.derivedCvcCustom = [CountVonCount countVonCount]; | |
| 270 [test_object setDerivedCvcNotProperty:[CountVonCount countVonCount]]; | |
| 271 | |
| 272 // That added 4 objects, plus 1 more that was copied. | |
| 273 EXPECT_EQ(13, ah_ah_ah); | |
| 274 | |
| 275 test_object.protoCvcRetain = [CountVonCount countVonCount]; | |
| 276 test_object.protoCvcCopy = [CountVonCount countVonCount]; | |
| 277 test_object.protoCvcAssign = protoAssign; | |
| 278 test_object.protoCvcCustom = [CountVonCount countVonCount]; | |
| 279 | |
| 280 // That added 3 objects, plus 1 more that was copied. | |
| 281 EXPECT_EQ(17, ah_ah_ah); | |
| 282 } | |
| 283 | |
| 284 // Now that the autorelease pool has been popped, the 3 objects that were | |
| 285 // copied when placed into the test object will have been deallocated. | |
| 286 EXPECT_EQ(14, ah_ah_ah); | |
| 287 | |
| 288 // Make sure that the setters work and have the expected semantics. | |
| 289 test_object.baseCvcRetain = nil; | |
| 290 test_object.baseCvcCopy = nil; | |
| 291 test_object.baseCvcAssign = nil; | |
| 292 test_object.baseCvcCustom = nil; | |
| 293 test_object.derivedCvcRetain = nil; | |
| 294 test_object.derivedCvcCopy = nil; | |
| 295 test_object.derivedCvcAssign = nil; | |
| 296 test_object.derivedCvcCustom = nil; | |
| 297 test_object.protoCvcRetain = nil; | |
| 298 test_object.protoCvcCopy = nil; | |
| 299 test_object.protoCvcAssign = nil; | |
| 300 test_object.protoCvcCustom = nil; | |
| 301 | |
| 302 // The CountVonCounts marked "retain" and "copy" should have been | |
| 303 // deallocated. Those marked assign should not have been. The only ones that | |
| 304 // should exist now are the ones marked "assign" and the ones held in | |
| 305 // non-property instance variables. | |
| 306 EXPECT_EQ(5, ah_ah_ah); | |
| 307 | |
| 308 { | |
| 309 base::mac::ScopedNSAutoreleasePool pool; | |
| 310 | |
| 311 // Put things back to how they were. | |
| 312 test_object.baseCvcRetain = [CountVonCount countVonCount]; | |
| 313 test_object.baseCvcCopy = [CountVonCount countVonCount]; | |
| 314 test_object.baseCvcAssign = baseAssign; | |
| 315 test_object.baseCvcCustom = [CountVonCount countVonCount]; | |
| 316 test_object.derivedCvcRetain = [CountVonCount countVonCount]; | |
| 317 test_object.derivedCvcCopy = [CountVonCount countVonCount]; | |
| 318 test_object.derivedCvcAssign = derivedAssign; | |
| 319 test_object.derivedCvcCustom = [CountVonCount countVonCount]; | |
| 320 test_object.protoCvcRetain = [CountVonCount countVonCount]; | |
| 321 test_object.protoCvcCopy = [CountVonCount countVonCount]; | |
| 322 test_object.protoCvcAssign = protoAssign; | |
| 323 test_object.protoCvcCustom = [CountVonCount countVonCount]; | |
| 324 | |
| 325 // 9 more CountVonCounts, 3 of which were copied. | |
| 326 EXPECT_EQ(17, ah_ah_ah); | |
| 327 } | |
| 328 | |
| 329 // Now that the autorelease pool has been popped, the 3 copies are gone. | |
| 330 EXPECT_EQ(14, ah_ah_ah); | |
| 331 | |
| 332 // Releasing the test object should get rid of everything that it owns. | |
| 333 [test_object release]; | |
| 334 | |
| 335 // The property releaser should have released all of the CountVonCounts | |
| 336 // associated with properties marked "retain" or "copy". The -dealloc | |
| 337 // methods in each should have released the single non-property objects in | |
| 338 // each. Only the CountVonCounts assigned to the properties marked "assign" | |
| 339 // should remain. | |
| 340 EXPECT_EQ(3, ah_ah_ah); | |
| 341 | |
| 342 [baseAssign release]; | |
| 343 [derivedAssign release]; | |
| 344 [protoAssign release]; | |
| 345 | |
| 346 // Zero! Zero counts! Ah, ah, ah. | |
| 347 EXPECT_EQ(0, ah_ah_ah); | |
| 348 } | |
| 349 | |
| 350 } // namespace | |
| OLD | NEW |