Add ICU message format support
[chromium-blink-merge.git] / base / mac / objc_property_releaser_unittest.mm
blob50f81a876206472af81c511f09f7d6310a8707a8
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.
5 #import <Foundation/Foundation.h>
7 #import "base/mac/objc_property_releaser.h"
8 #import "base/mac/scoped_nsautorelease_pool.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 // "When I'm alone, I count myself."
12 //   --Count von Count, http://www.youtube.com/watch?v=FKzszqa9WA4
14 namespace {
16 // The number of CountVonCounts outstanding.
17 int ah_ah_ah;
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;
36 }  // namespace
38 @interface CountVonCount : NSObject<NSCopying>
40 + (CountVonCount*)countVonCount;
42 @end  // @interface CountVonCount
44 @implementation CountVonCount
46 + (CountVonCount*)countVonCount {
47   return [[[CountVonCount alloc] init] autorelease];
50 - (id)init {
51   ++ah_ah_ah;
52   return [super init];
55 - (void)dealloc {
56   --ah_ah_ah;
57   [super dealloc];
60 - (id)copyWithZone:(NSZone*)zone {
61   return [[CountVonCount allocWithZone:zone] init];
64 @end  // @implementation CountVonCount
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_;
79   base::mac::ObjCPropertyReleaser propertyReleaser_ObjCPropertyTestBase_;
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;
94 - (void)setBaseCvcNotProperty:(CountVonCount*)cvc;
96 @end  // @interface ObjCPropertyTestBase
98 @implementation ObjCPropertyTestBase
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_;
111 - (id)init {
112   if ((self = [super init])) {
113     propertyReleaser_ObjCPropertyTestBase_.Init(
114         self, [ObjCPropertyTestBase class]);
115   }
116   return self;
119 - (void)dealloc {
120   [baseCvcNotProperty_ release];
121   [super dealloc];
124 - (void)setBaseCvcNotProperty:(CountVonCount*)cvc {
125   if (cvc != baseCvcNotProperty_) {
126     [baseCvcNotProperty_ release];
127     baseCvcNotProperty_ = [cvc retain];
128   }
131 @end  // @implementation ObjCPropertyTestBase
133 @protocol ObjCPropertyTestProtocol
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;
147 @end  // @protocol ObjCPropertyTestProtocol
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_;
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_;
173   base::mac::ObjCPropertyReleaser propertyReleaser_ObjCPropertyTestDerived_;
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;
188 - (void)setDerivedCvcNotProperty:(CountVonCount*)cvc;
190 @end  // @interface ObjCPropertyTestDerived
192 @implementation ObjCPropertyTestDerived
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_;
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_;
216 - (id)init {
217   if ((self = [super init])) {
218     propertyReleaser_ObjCPropertyTestDerived_.Init(
219         self, [ObjCPropertyTestDerived class]);
220   }
221   return self;
224 - (void)dealloc {
225   [derivedCvcNotProperty_ release];
226   [super dealloc];
229 - (void)setDerivedCvcNotProperty:(CountVonCount*)cvc {
230   if (cvc != derivedCvcNotProperty_) {
231     [derivedCvcNotProperty_ release];
232     derivedCvcNotProperty_ = [cvc retain];
233   }
236 @end  // @implementation ObjCPropertyTestDerived
238 namespace {
240 TEST(ObjCPropertyReleaserTest, SesameStreet) {
241   ObjCPropertyTestDerived* test_object = [[ObjCPropertyTestDerived alloc] init];
243   // Assure a clean slate.
244   EXPECT_EQ(0, ah_ah_ah);
245   EXPECT_EQ(1U, [test_object retainCount]);
247   CountVonCount* baseAssign = [[CountVonCount alloc] init];
248   CountVonCount* derivedAssign = [[CountVonCount alloc] init];
249   CountVonCount* protoAssign = [[CountVonCount alloc] init];
251   // Make sure that worked before things get more involved.
252   EXPECT_EQ(3, ah_ah_ah);
254   {
255     base::mac::ScopedNSAutoreleasePool pool;
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]];
263     // That added 4 objects, plus 1 more that was copied.
264     EXPECT_EQ(8, ah_ah_ah);
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]];
272     // That added 4 objects, plus 1 more that was copied.
273     EXPECT_EQ(13, ah_ah_ah);
275     test_object.protoCvcRetain = [CountVonCount countVonCount];
276     test_object.protoCvcCopy = [CountVonCount countVonCount];
277     test_object.protoCvcAssign = protoAssign;
278     test_object.protoCvcCustom = [CountVonCount countVonCount];
280     // That added 3 objects, plus 1 more that was copied.
281     EXPECT_EQ(17, ah_ah_ah);
282   }
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);
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;
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);
308   {
309     base::mac::ScopedNSAutoreleasePool pool;
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];
325     // 9 more CountVonCounts, 3 of which were copied.
326     EXPECT_EQ(17, ah_ah_ah);
327   }
329   // Now that the autorelease pool has been popped, the 3 copies are gone.
330   EXPECT_EQ(14, ah_ah_ah);
332   // Releasing the test object should get rid of everything that it owns.
333   [test_object release];
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);
342   [baseAssign release];
343   [derivedAssign release];
344   [protoAssign release];
346   // Zero! Zero counts! Ah, ah, ah.
347   EXPECT_EQ(0, ah_ah_ah);
350 }  // namespace