aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AppKit/GTMLargeTypeWindow.h2
-rw-r--r--AppKit/GTMLargeTypeWindowTest.m4
-rwxr-xr-xBuildScripts/BuildAllSDKs.sh35
-rw-r--r--Foundation/GTMExceptionalInlines.h1
-rw-r--r--Foundation/GTMExceptionalInlines.m4
-rw-r--r--Foundation/GTMExceptionalInlinesTest.m6
-rw-r--r--Foundation/GTMHTTPServer.m1
-rw-r--r--Foundation/GTMPathTest.m1
-rw-r--r--Foundation/GTMRegex.m2
-rw-r--r--GTM.xcodeproj/project.pbxproj80
-rw-r--r--GTMiPhone.xcodeproj/project.pbxproj63
-rw-r--r--ReleaseNotes.txt13
-rw-r--r--UnitTesting/GTMIPhoneUnitTestDelegate.m40
-rw-r--r--UnitTesting/GTMNSObject+UnitTesting.m2
-rw-r--r--UnitTesting/GTMTestTimer.h125
-rw-r--r--UnitTesting/GTMTestTimerTest.m56
-rwxr-xr-xUnitTesting/RunIPhoneUnitTest.sh37
-rwxr-xr-xUnitTesting/RunMacOSUnitTests.sh45
-rw-r--r--XcodeConfig/Project/DebugiPhone.xcconfig18
-rw-r--r--XcodeConfig/Project/DebugiPhone20.xcconfig34
-rw-r--r--XcodeConfig/Project/DebugiPhone21.xcconfig34
-rw-r--r--XcodeConfig/Project/ReleaseiPhone.xcconfig18
-rw-r--r--XcodeConfig/Project/ReleaseiPhone20.xcconfig34
-rw-r--r--XcodeConfig/Project/ReleaseiPhone21.xcconfig34
-rw-r--r--XcodeConfig/subconfig/General.xcconfig2
-rw-r--r--XcodeConfig/subconfig/iPhone20.xcconfig (renamed from XcodeConfig/subconfig/iPhone.xcconfig)6
-rw-r--r--XcodeConfig/subconfig/iPhone21.xcconfig26
-rw-r--r--iPhone/GTMABAddressBook.m3
-rw-r--r--iPhone/GTMABAddressBookTest.m33
29 files changed, 671 insertions, 88 deletions
diff --git a/AppKit/GTMLargeTypeWindow.h b/AppKit/GTMLargeTypeWindow.h
index 52316fc..c898512 100644
--- a/AppKit/GTMLargeTypeWindow.h
+++ b/AppKit/GTMLargeTypeWindow.h
@@ -28,7 +28,7 @@
// = [[[GTMLargeTypeWindow alloc] initWithString:@"Foo"] autorelease];
// [window makeKeyAndOrderFront:nil];
-// NB This class appears to have a problem with GC on 10.5.4 and below.
+// NB This class appears to have a problem with GC on 10.5.5 and below.
// Radar 6137322 CIFilter crashing when run with GC enabled
// This appears to be an Apple bug with GC.
// We do a copy animation that causes things to crash, but only with GC
diff --git a/AppKit/GTMLargeTypeWindowTest.m b/AppKit/GTMLargeTypeWindowTest.m
index d9e56c2..36e60c3 100644
--- a/AppKit/GTMLargeTypeWindowTest.m
+++ b/AppKit/GTMLargeTypeWindowTest.m
@@ -62,12 +62,12 @@ NSString *const kShortTextBlock = @"Short";
// See the comment/warning in the GTMLargeTypeWindow.h for more details,
// but we disable them to avoid the tests failing (crashing) when it's Apple's
// bug. Please bump the system check as appropriate when new systems are
- // tested. Currently broken on 10.5.4 and below.
+ // tested. Currently broken on 10.5.5 and below.
// Radar 6137322 CIFilter crashing when run with GC enabled
long major, minor, bugfix;
[GTMSystemVersion getMajor:&major minor:&minor bugFix:&bugfix];
if (!(GTMIsGarbageCollectionEnabled()
- && major <= 10 && minor <= 5 && bugfix <= 4)) {
+ && major <= 10 && minor <= 5 && bugfix <= 5)) {
return YES;
} else {
NSLog(@"--- animated copy not run because of GC incompatibilites ---");
diff --git a/BuildScripts/BuildAllSDKs.sh b/BuildScripts/BuildAllSDKs.sh
index 0928dcd..1e08940 100755
--- a/BuildScripts/BuildAllSDKs.sh
+++ b/BuildScripts/BuildAllSDKs.sh
@@ -1,7 +1,7 @@
#!/bin/sh
# BuildAllSDKs.sh
#
-# This script builds both the Tiger and Leopard versions of the requested
+# This script builds the Tiger, Leopard and iPhone versions of the requested
# target in the current basic config (debug, release, debug-gcov).
#
# Copyright 2006-2008 Google Inc.
@@ -18,21 +18,37 @@
# License for the specific language governing permissions and limitations under
# the License.
-PROJECT_TARGET="$1"
+GTM_PROJECT_TARGET="$1"
+GTMIPHONE_PROJECT_TARGET="$2"
STARTING_TARGET="${TARGET_NAME}"
SCRIPT_APP="${TMPDIR}DoBuild.app"
-REQUESTED_BUILD_STYLE=$(echo "${BUILD_STYLE}" | sed "s/.*OrLater-\(.*\)/\1/")
+REQUESTED_BUILD_STYLE=$(echo "${BUILD_STYLE}" | sed -E "s/(.*OrLater-)?(.*)/\2/")
# See if we were told to clean instead of build.
PROJECT_ACTION="build"
if [ "${ACTION}" == "clean" ]; then
PROJECT_ACTION="clean"
fi
-# build up our AppleScript
+# build up our GTMiPhone parts
+GTMIPHONE_OPEN_EXTRAS=""
+GTMIPHONE_BUILD_EXTRAS=""
+if [ "${GTMIPHONE_PROJECT_TARGET}" != "" ]; then
+ GTMIPHONE_OPEN_EXTRAS="-- make sure both project files are open
+ open posix file \"${SRCROOT}/GTM.xcodeproj\"
+ open posix file \"${SRCROOT}/GTMiPhone.xcodeproj\""
+ GTMIPHONE_BUILD_EXTRAS="tell project \"GTMiPhone\"
+ -- do the GTMiPhone build
+ ${PROJECT_ACTION} using build configuration \"${REQUESTED_BUILD_STYLE}\"
+ set active target to target \"${STARTING_TARGET}\"
+ end tell"
+fi
+
+# build up our GTM AppleScript
OUR_BUILD_SCRIPT="on run
tell application \"Xcode\"
activate
+ ${GTMIPHONE_OPEN_EXTRAS}
tell project \"GTM\"
-- wait for build to finish
set x to 0
@@ -44,19 +60,22 @@ OUR_BUILD_SCRIPT="on run
return
end if
end repeat
- -- do the build
+ -- do the GTM builds
with timeout of 9999 seconds
- set active target to target \"${PROJECT_TARGET}\"
+ set active target to target \"${GTM_PROJECT_TARGET}\"
set buildResult to ${PROJECT_ACTION} using build configuration \"TigerOrLater-${REQUESTED_BUILD_STYLE}\"
if buildResult is not equal to \"Build succeeded\" then
set active target to target \"${STARTING_TARGET}\"
return
end if
- -- do not need the result since we are not doing another build
- ${PROJECT_ACTION} using build configuration \"LeopardOrLater-${REQUESTED_BUILD_STYLE}\"
+ set buildResult to ${PROJECT_ACTION} using build configuration \"LeopardOrLater-${REQUESTED_BUILD_STYLE}\"
set active target to target \"${STARTING_TARGET}\"
+ if buildResult is not equal to \"Build succeeded\" then
+ return
+ end if
end timeout
end tell
+ ${GTMIPHONE_BUILD_EXTRAS}
end tell
end run"
diff --git a/Foundation/GTMExceptionalInlines.h b/Foundation/GTMExceptionalInlines.h
index 25635c1..ce30db9 100644
--- a/Foundation/GTMExceptionalInlines.h
+++ b/Foundation/GTMExceptionalInlines.h
@@ -37,6 +37,7 @@
// functions where possible.
FOUNDATION_EXPORT NSRange GTMNSMakeRange(NSUInteger loc, NSUInteger len);
+FOUNDATION_EXPORT CFRange GTMCFRangeMake(NSUInteger loc, NSUInteger len);
FOUNDATION_EXPORT CGPoint GTMCGPointMake(CGFloat x, CGFloat y);
FOUNDATION_EXPORT CGSize GTMCGSizeMake(CGFloat width, CGFloat height);
diff --git a/Foundation/GTMExceptionalInlines.m b/Foundation/GTMExceptionalInlines.m
index 120e235..d803ea9 100644
--- a/Foundation/GTMExceptionalInlines.m
+++ b/Foundation/GTMExceptionalInlines.m
@@ -22,6 +22,10 @@ NSRange GTMNSMakeRange(NSUInteger loc, NSUInteger len) {
return NSMakeRange(loc, len);
}
+CFRange GTMCFRangeMake(NSUInteger loc, NSUInteger len) {
+ return CFRangeMake(loc, len);
+}
+
CGPoint GTMCGPointMake(CGFloat x, CGFloat y) {
return CGPointMake(x, y);
}
diff --git a/Foundation/GTMExceptionalInlinesTest.m b/Foundation/GTMExceptionalInlinesTest.m
index f785301..6142236 100644
--- a/Foundation/GTMExceptionalInlinesTest.m
+++ b/Foundation/GTMExceptionalInlinesTest.m
@@ -35,6 +35,12 @@
NSRange range1 = GTMNSMakeRange(loc, len);
NSRange range2 = NSMakeRange(loc, len);
STAssertTrue(NSEqualRanges(range1, range2), nil);
+
+ CFRange cfrange1 = GTMCFRangeMake(loc, len);
+ CFRange cfrange2 = CFRangeMake(loc, len);
+ STAssertEquals(cfrange1.length, cfrange2.length, nil);
+ STAssertEquals(cfrange1.location, cfrange2.location, nil);
+
CGPoint cgpoint1 = GTMCGPointMake(x, y);
CGPoint cgpoint2 = CGPointMake(x, y);
diff --git a/Foundation/GTMHTTPServer.m b/Foundation/GTMHTTPServer.m
index ffa294c..ecd649c 100644
--- a/Foundation/GTMHTTPServer.m
+++ b/Foundation/GTMHTTPServer.m
@@ -90,6 +90,7 @@ static NSString *kResponse = @"Response";
- (void)dealloc {
[self stop];
+ [connections_ release];
[super dealloc];
}
diff --git a/Foundation/GTMPathTest.m b/Foundation/GTMPathTest.m
index 0570bb3..3a60ea7 100644
--- a/Foundation/GTMPathTest.m
+++ b/Foundation/GTMPathTest.m
@@ -51,6 +51,7 @@
#else
[[NSFileManager defaultManager] removeItemAtPath:testDirectory_ error:NULL];
#endif
+ [testDirectory_ release];
}
- (void)testBasicCreation {
diff --git a/Foundation/GTMRegex.m b/Foundation/GTMRegex.m
index c142c62..33c5b25 100644
--- a/Foundation/GTMRegex.m
+++ b/Foundation/GTMRegex.m
@@ -674,6 +674,8 @@ static NSString *const kReplacementPattern =
- (id)init {
// make sure init is never called, the class in in the header so someone
// could try to create it by mistake.
+ // Call super init and release so we don't leak
+ [[super init] autorelease];
[self doesNotRecognizeSelector:_cmd];
return nil; // COV_NF_LINE - return is just here to keep gcc happy
}
diff --git a/GTM.xcodeproj/project.pbxproj b/GTM.xcodeproj/project.pbxproj
index 9fb14d1..9d958a4 100644
--- a/GTM.xcodeproj/project.pbxproj
+++ b/GTM.xcodeproj/project.pbxproj
@@ -16,6 +16,7 @@
8B45A0390DA46A20001148C5 /* PBXTargetDependency */,
F472042F0D33BEB500E9F378 /* PBXTargetDependency */,
F472042D0D33BEB500E9F378 /* PBXTargetDependency */,
+ 8B5A9D120E717906005DA441 /* PBXTargetDependency */,
);
name = "All UnitTests";
productName = "All UnitTests";
@@ -61,6 +62,8 @@
8B3344250DBF7A36009FD32C /* GTMNSAppleEventDescriptor+FoundationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B33441D0DBF7A36009FD32C /* GTMNSAppleEventDescriptor+FoundationTest.m */; };
8B33455E0DBF8844009FD32C /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F42E09AD0D19A62F00D5DDE0 /* Carbon.framework */; };
8B3345890DBF8A55009FD32C /* GTMNSAppleEvent+HandlerTest.applescript in AppleScript */ = {isa = PBXBuildFile; fileRef = 8B3344200DBF7A36009FD32C /* GTMNSAppleEvent+HandlerTest.applescript */; settings = {ATTRIBUTES = (Debug, ); }; };
+ 8B3590160E8190FA0041E21C /* GTMTestTimer.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B3590150E8190FA0041E21C /* GTMTestTimer.h */; };
+ 8B35901B0E8191750041E21C /* GTMTestTimerTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B35901A0E8191750041E21C /* GTMTestTimerTest.m */; };
8B3AA9F10E033E23007E31B5 /* GTMValidatingContainers.h in Headers */ = {isa = PBXBuildFile; fileRef = 8B3AA9EF0E033E23007E31B5 /* GTMValidatingContainers.h */; settings = {ATTRIBUTES = (Public, ); }; };
8B3AA9F20E033E23007E31B5 /* GTMValidatingContainers.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B3AA9F00E033E23007E31B5 /* GTMValidatingContainers.m */; };
8B3AA9F80E033E5F007E31B5 /* GTMValidatingContainersTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B3AA9F70E033E5F007E31B5 /* GTMValidatingContainersTest.m */; };
@@ -243,6 +246,20 @@
remoteGlobalIDString = 8B45A2890DA49B99001148C5;
remoteInfo = UIUnitTestingHarness;
};
+ 8B5A9D0F0E7178F6005DA441 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 8B5A9D070E7178F6005DA441 /* GTMiPhone.xcodeproj */;
+ proxyType = 2;
+ remoteGlobalIDString = 1D6058910D05DD3D006BFB54;
+ remoteInfo = GTMiPhoneUnitTesting;
+ };
+ 8B5A9D110E717906005DA441 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 8B5A9D070E7178F6005DA441 /* GTMiPhone.xcodeproj */;
+ proxyType = 1;
+ remoteGlobalIDString = F4C7F9BF0DC62EC8009BEE5B;
+ remoteInfo = "All UnitTests";
+ };
8B7DCBA30DFF0EFB0017E983 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 0867D690FE84028FC02AAC07 /* Project object */;
@@ -324,6 +341,8 @@
8B33441E0DBF7A36009FD32C /* GTMNSAppleEventDescriptor+Foundation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMNSAppleEventDescriptor+Foundation.m"; sourceTree = "<group>"; };
8B33441F0DBF7A36009FD32C /* GTMNSAppleEventDescriptor+Foundation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMNSAppleEventDescriptor+Foundation.h"; sourceTree = "<group>"; };
8B3344200DBF7A36009FD32C /* GTMNSAppleEvent+HandlerTest.applescript */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.applescript; path = "GTMNSAppleEvent+HandlerTest.applescript"; sourceTree = "<group>"; };
+ 8B3590150E8190FA0041E21C /* GTMTestTimer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMTestTimer.h; sourceTree = "<group>"; };
+ 8B35901A0E8191750041E21C /* GTMTestTimerTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMTestTimerTest.m; sourceTree = "<group>"; };
8B3AA9EF0E033E23007E31B5 /* GTMValidatingContainers.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMValidatingContainers.h; sourceTree = "<group>"; };
8B3AA9F00E033E23007E31B5 /* GTMValidatingContainers.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMValidatingContainers.m; sourceTree = "<group>"; };
8B3AA9F70E033E5F007E31B5 /* GTMValidatingContainersTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMValidatingContainersTest.m; sourceTree = "<group>"; };
@@ -344,6 +363,7 @@
8B55479A0DB3B7A50014CC1C /* GTMAppKit+UnitTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GTMAppKit+UnitTesting.h"; sourceTree = "<group>"; };
8B55479B0DB3B7A50014CC1C /* GTMAppKit+UnitTesting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GTMAppKit+UnitTesting.m"; sourceTree = "<group>"; };
8B58E9940E547EB000A0E02E /* GTMGetURLHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMGetURLHandler.m; sourceTree = "<group>"; };
+ 8B5A9D070E7178F6005DA441 /* GTMiPhone.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = GTMiPhone.xcodeproj; sourceTree = "<group>"; };
8B61FDBF0E4CDB8000FF9C21 /* GTMStackTrace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMStackTrace.m; sourceTree = "<group>"; };
8B6F31EF0DA347720052CA40 /* GTMMethodCheck.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMMethodCheck.m; sourceTree = "<group>"; };
8B6F31F10DA347720052CA40 /* GTMMethodCheckTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMMethodCheckTest.m; sourceTree = "<group>"; };
@@ -563,6 +583,7 @@
0867D691FE84028FC02AAC07 /* GTM */ = {
isa = PBXGroup;
children = (
+ 8B5A9D070E7178F6005DA441 /* GTMiPhone.xcodeproj */,
F4C978090D5B79C7001C29A6 /* ReleaseNotes.txt */,
F440EDB70DFECC4B0003E81F /* BuildingAndUsing.txt */,
8B1A16050D90344B00CA1E8E /* GTMDefines.h */,
@@ -606,6 +627,14 @@
path = GTMUIUnitTestingHarness;
sourceTree = "<group>";
};
+ 8B5A9D080E7178F6005DA441 /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 8B5A9D100E7178F6005DA441 /* GTMiPhoneTest.app */,
+ );
+ name = Products;
+ sourceTree = "<group>";
+ };
F435E46C0DC8F23A0069CDE8 /* TestData */ = {
isa = PBXGroup;
children = (
@@ -804,27 +833,29 @@
F48FE2770D198CEA009257D2 /* UnitTesting */ = {
isa = PBXGroup;
children = (
- 8B7DCBE10DFF18720017E983 /* GTMDevLogUnitTestingBridge.m */,
- 8B7DCBEC0DFF1A4F0017E983 /* GTMUnitTestDevLog.m */,
- 8B7DCBF00DFF1A610017E983 /* GTMUnitTestDevLog.h */,
- F4BC22CF0DE4C39000108B7D /* GTMTestHTTPServer.h */,
- F4BC22D00DE4C39000108B7D /* GTMTestHTTPServer.m */,
- 8BC04D140DB0061300C2D1CA /* RunMacOSUnitTests.sh */,
8B55479A0DB3B7A50014CC1C /* GTMAppKit+UnitTesting.h */,
8B55479B0DB3B7A50014CC1C /* GTMAppKit+UnitTesting.m */,
- 8B726BD00D91C0860090C251 /* GTMCALayer+UnitTesting.m */,
8B726BD10D91C0860090C251 /* GTMCALayer+UnitTesting.h */,
+ 8B726BD00D91C0860090C251 /* GTMCALayer+UnitTesting.m */,
+ 8B7DCBE10DFF18720017E983 /* GTMDevLogUnitTestingBridge.m */,
+ 8B1A14EA0D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.h */,
+ 8B1A14E90D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.m */,
F48FE29B0D198D36009257D2 /* GTMNSObject+UnitTesting.h */,
F48FE29C0D198D36009257D2 /* GTMNSObject+UnitTesting.m */,
- 8B1A14E90D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.m */,
- 8B1A14EA0D900BC800CA1E8E /* GTMNSObject+BindingUnitTesting.h */,
- 8B45A2670DA498A0001148C5 /* GTMUnitTestingUtilities.h */,
- 8B45A2680DA498A0001148C5 /* GTMUnitTestingUtilities.m */,
F48FE29F0D198D36009257D2 /* GTMSenTestCase.h */,
8B7DCE180DFF39850017E983 /* GTMSenTestCase.m */,
+ F4BC22CF0DE4C39000108B7D /* GTMTestHTTPServer.h */,
+ F4BC22D00DE4C39000108B7D /* GTMTestHTTPServer.m */,
+ 8B3590150E8190FA0041E21C /* GTMTestTimer.h */,
+ 8B35901A0E8191750041E21C /* GTMTestTimerTest.m */,
+ 8B7DCBF00DFF1A610017E983 /* GTMUnitTestDevLog.h */,
+ 8B7DCBEC0DFF1A4F0017E983 /* GTMUnitTestDevLog.m */,
+ 8B7AD4AD0DABBFEE00B84F4A /* GTMUnitTestingBindingTest.m */,
8B45A2E00DA51ABC001148C5 /* GTMUnitTestingTest.h */,
8B45A2E10DA51ABC001148C5 /* GTMUnitTestingTest.m */,
- 8B7AD4AD0DABBFEE00B84F4A /* GTMUnitTestingBindingTest.m */,
+ 8B45A2670DA498A0001148C5 /* GTMUnitTestingUtilities.h */,
+ 8B45A2680DA498A0001148C5 /* GTMUnitTestingUtilities.m */,
+ 8BC04D140DB0061300C2D1CA /* RunMacOSUnitTests.sh */,
8B45A2A20DA49C47001148C5 /* GTMUIUnitTestingHarness */,
F435E46C0DC8F23A0069CDE8 /* TestData */,
);
@@ -920,6 +951,7 @@
F95803FA0E2FB08F0049A088 /* GTMLoggerRingBufferWriter.h in Headers */,
8B1B49180E5F8E2100A08972 /* GTMExceptionalInlines.h in Headers */,
7F3EB38E0E5E09C700A7A75E /* GTMNSImage+Scaling.h in Headers */,
+ 8B3590160E8190FA0041E21C /* GTMTestTimer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -942,7 +974,7 @@
};
F41A6EF80E02DCFC00788A6C /* All UnitTests All SDKs */ = {
isa = PBXLegacyTarget;
- buildArgumentsString = "\"All UnitTests\"";
+ buildArgumentsString = "\"All UnitTests\" \"All UnitTests\"";
buildConfigurationList = F41A6F070E02DD1500788A6C /* Build configuration list for PBXLegacyTarget "All UnitTests All SDKs" */;
buildPhases = (
);
@@ -1066,6 +1098,12 @@
mainGroup = 0867D691FE84028FC02AAC07 /* GTM */;
productRefGroup = 034768DFFF38A50411DB9C8B /* Products */;
projectDirPath = "";
+ projectReferences = (
+ {
+ ProductGroup = 8B5A9D080E7178F6005DA441 /* Products */;
+ ProjectRef = 8B5A9D070E7178F6005DA441 /* GTMiPhone.xcodeproj */;
+ },
+ );
projectRoot = "";
targets = (
F42E086C0D199A5B00D5DDE0 /* GTM */,
@@ -1080,6 +1118,16 @@
};
/* End PBXProject section */
+/* Begin PBXReferenceProxy section */
+ 8B5A9D100E7178F6005DA441 /* GTMiPhoneTest.app */ = {
+ isa = PBXReferenceProxy;
+ fileType = wrapper.application;
+ path = GTMiPhoneTest.app;
+ remoteRef = 8B5A9D0F0E7178F6005DA441 /* PBXContainerItemProxy */;
+ sourceTree = BUILT_PRODUCTS_DIR;
+ };
+/* End PBXReferenceProxy section */
+
/* Begin PBXResourcesBuildPhase section */
8B45A0230DA4696C001148C5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
@@ -1196,6 +1244,7 @@
8B7DCBC30DFF0F7F0017E983 /* GTMMethodCheck.m in Sources */,
8B7DCBEF0DFF1A4F0017E983 /* GTMUnitTestDevLog.m in Sources */,
8B7DCE1B0DFF39850017E983 /* GTMSenTestCase.m in Sources */,
+ 8B35901B0E8191750041E21C /* GTMTestTimerTest.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1335,6 +1384,11 @@
target = 8B45A2890DA49B99001148C5 /* UIUnitTestingHarness */;
targetProxy = 8B45A2D30DA51A0E001148C5 /* PBXContainerItemProxy */;
};
+ 8B5A9D120E717906005DA441 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ name = "All UnitTests";
+ targetProxy = 8B5A9D110E717906005DA441 /* PBXContainerItemProxy */;
+ };
8B7DCBA40DFF0EFB0017E983 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = F42E086C0D199A5B00D5DDE0 /* GTM */;
diff --git a/GTMiPhone.xcodeproj/project.pbxproj b/GTMiPhone.xcodeproj/project.pbxproj
index bf1133b..f470ec8 100644
--- a/GTMiPhone.xcodeproj/project.pbxproj
+++ b/GTMiPhone.xcodeproj/project.pbxproj
@@ -174,8 +174,8 @@
8BC048000DAE928A00C2D1CA /* GTMUIViewUnitTestingTest.gtmUTState */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = GTMUIViewUnitTestingTest.gtmUTState; sourceTree = "<group>"; };
8BC048010DAE928A00C2D1CA /* GTMUIViewUnitTestingTest.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = GTMUIViewUnitTestingTest.png; sourceTree = "<group>"; };
8BC0480E0DAE928A00C2D1CA /* RunIPhoneUnitTest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = RunIPhoneUnitTest.sh; sourceTree = "<group>"; };
- 8BC049850DAEC59100C2D1CA /* DebugiPhone.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugiPhone.xcconfig; sourceTree = "<group>"; };
- 8BC049890DAEC59100C2D1CA /* ReleaseiPhone.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseiPhone.xcconfig; sourceTree = "<group>"; };
+ 8BC049850DAEC59100C2D1CA /* DebugiPhone20.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = DebugiPhone20.xcconfig; sourceTree = "<group>"; };
+ 8BC049890DAEC59100C2D1CA /* ReleaseiPhone20.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = ReleaseiPhone20.xcconfig; sourceTree = "<group>"; };
8BC0498F0DAEC59100C2D1CA /* CodeCoverage.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = CodeCoverage.xcconfig; sourceTree = "<group>"; };
8BC04A6F0DAF144200C2D1CA /* GTMSystemVersion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMSystemVersion.h; sourceTree = "<group>"; };
8BC04A710DAF144700C2D1CA /* GTMSystemVersionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMSystemVersionTest.m; sourceTree = "<group>"; };
@@ -425,8 +425,8 @@
8BC04F020DB15A5300C2D1CA /* Project */ = {
isa = PBXGroup;
children = (
- 8BC049850DAEC59100C2D1CA /* DebugiPhone.xcconfig */,
- 8BC049890DAEC59100C2D1CA /* ReleaseiPhone.xcconfig */,
+ 8BC049850DAEC59100C2D1CA /* DebugiPhone20.xcconfig */,
+ 8BC049890DAEC59100C2D1CA /* ReleaseiPhone20.xcconfig */,
);
path = Project;
sourceTree = "<group>";
@@ -441,6 +441,23 @@
};
/* End PBXGroup section */
+/* Begin PBXLegacyTarget section */
+ F4B541440E7F022B004738EC /* All UnitTests all SDKs */ = {
+ isa = PBXLegacyTarget;
+ buildArgumentsString = "\"All UnitTests\" \"All UnitTests\"";
+ buildConfigurationList = F4B5414A0E7F025F004738EC /* Build configuration list for PBXLegacyTarget "All UnitTests all SDKs" */;
+ buildPhases = (
+ );
+ buildToolPath = BuildScripts/BuildAllSDKs.sh;
+ buildWorkingDirectory = "$(SRCROOT)";
+ dependencies = (
+ );
+ name = "All UnitTests all SDKs";
+ passBuildSettingsInEnvironment = 1;
+ productName = "All UnitTests all SDKs";
+ };
+/* End PBXLegacyTarget section */
+
/* Begin PBXNativeTarget section */
1D6058900D05DD3D006BFB54 /* GTMiPhoneUnitTesting */ = {
isa = PBXNativeTarget;
@@ -474,6 +491,7 @@
targets = (
F4C7F9BF0DC62EC8009BEE5B /* All UnitTests */,
1D6058900D05DD3D006BFB54 /* GTMiPhoneUnitTesting */,
+ F4B541440E7F022B004738EC /* All UnitTests all SDKs */,
);
};
/* End PBXProject section */
@@ -600,7 +618,7 @@
};
8BC0497D0DAEC48600C2D1CA /* Debug-gcov */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 8BC049850DAEC59100C2D1CA /* DebugiPhone.xcconfig */;
+ baseConfigurationReference = 8BC049850DAEC59100C2D1CA /* DebugiPhone20.xcconfig */;
buildSettings = {
GCC_PREFIX_HEADER = GTM_Prefix.pch;
SDKROOT = iphonesimulator2.0;
@@ -618,7 +636,7 @@
};
C01FCF4F08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 8BC049850DAEC59100C2D1CA /* DebugiPhone.xcconfig */;
+ baseConfigurationReference = 8BC049850DAEC59100C2D1CA /* DebugiPhone20.xcconfig */;
buildSettings = {
GCC_PREFIX_HEADER = GTM_Prefix.pch;
SDKROOT = iphonesimulator2.0;
@@ -627,13 +645,34 @@
};
C01FCF5008A954540054247B /* Release */ = {
isa = XCBuildConfiguration;
- baseConfigurationReference = 8BC049890DAEC59100C2D1CA /* ReleaseiPhone.xcconfig */;
+ baseConfigurationReference = 8BC049890DAEC59100C2D1CA /* ReleaseiPhone20.xcconfig */;
buildSettings = {
GCC_PREFIX_HEADER = GTM_Prefix.pch;
SDKROOT = iphonesimulator2.0;
};
name = Release;
};
+ F4B541450E7F022B004738EC /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "All UnitTests all SDKs";
+ };
+ name = Debug;
+ };
+ F4B541460E7F022B004738EC /* Debug-gcov */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "All UnitTests all SDKs";
+ };
+ name = "Debug-gcov";
+ };
+ F4B541470E7F022B004738EC /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ PRODUCT_NAME = "All UnitTests all SDKs";
+ };
+ name = Release;
+ };
F4C7F9C00DC62EC8009BEE5B /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@@ -678,6 +717,16 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
+ F4B5414A0E7F025F004738EC /* Build configuration list for PBXLegacyTarget "All UnitTests all SDKs" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ F4B541450E7F022B004738EC /* Debug */,
+ F4B541460E7F022B004738EC /* Debug-gcov */,
+ F4B541470E7F022B004738EC /* Release */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
F4C7F9C50DC62F0C009BEE5B /* Build configuration list for PBXAggregateTarget "All UnitTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt
index 5dbfe96..1f39568 100644
--- a/ReleaseNotes.txt
+++ b/ReleaseNotes.txt
@@ -99,6 +99,19 @@ Changes since 1.5.1
- Added several set environment variable statements to RunIPhoneUnitTest.sh
to encourage bugs to come out of the woodwork.
+- Added GTMTestTimer.h for doing high fidelity timings.
+
+- Added leaks checking to iPhone unit test script. It can be controlled by
+ the GTM_DISABLE_LEAKS environment variable
+
+- Added ability to control using zombies to iPhone unit test script. It can be
+ controlled by the GTM_DISABLE_ZOMBIES environment variable
+
+- Added ability to control termination to iPhone unit test script. It can be
+ controlled by the GTM_DISABLE_TERMINATION environment variable
+
+- Fixed several leaks found with leak checking enabled.
+
Release 1.5.1
Changes since 1.5.0
diff --git a/UnitTesting/GTMIPhoneUnitTestDelegate.m b/UnitTesting/GTMIPhoneUnitTestDelegate.m
index f93c472..a793ff4 100644
--- a/UnitTesting/GTMIPhoneUnitTestDelegate.m
+++ b/UnitTesting/GTMIPhoneUnitTestDelegate.m
@@ -34,6 +34,33 @@ static int MethodSort(const void *a, const void *b) {
return strcmp(nameA, nameB);
}
+static void RunLeaks(void) {
+ // This is an atexit handler. It runs leaks for us to check if we are
+ // leaking anything in our tests. Note that leaks and NSZombieEnabled
+ // don't play well together, so we attempt to filter out the zombies from
+ // our leaks when NSZombieEnabled is on.
+ BOOL zombiesOn = getenv("NSZombieEnabled") != NULL;
+ NSString *filterZombies = @"| grep -v _NSZombie";
+ NSString *zombieExplanation = @"echo 'Leaks:0: note: NSZombies being "
+ @"filtered from leaks. If zombies are on, ignore the \"x leaks for y total "
+ @"leaked bytes.\" line above unless actual leaks are reported. "
+ @"Set the 'GTM_DISABLE_ZOMBIES' environment variable to turn off "
+ @"zombies, and to get more information about the leaks.'";
+ NSString *string
+ = [NSString stringWithFormat:@"/usr/bin/leaks %@ %d %@"
+ @"| /usr/bin/sed \"s/Leak: /Leaks:0: warning: Leak /\"; %@",
+ zombiesOn ? @"-nocontext -nostacks" : @"",
+ getpid(),
+ zombiesOn ? filterZombies : @"",
+ zombiesOn ? zombieExplanation : @""];
+ int ret = system([string UTF8String]);
+ if (ret) {
+ fprintf(stderr, "%s:%d: Error: Unable to run leaks. 'system' returned: %d",
+ __FILE__, __LINE__, ret);
+ fflush(stderr);
+ }
+}
+
@interface UIApplication (iPhoneUnitTestAdditions)
// "Private" method that we need
- (void)terminate;
@@ -58,9 +85,20 @@ static int MethodSort(const void *a, const void *b) {
// that are subclasses of SenTestCase. Terminate the application upon
// test completion.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
+ // Don't want to get leaks on the device as the device doesn't
+ // have 'leaks'. We check for this by looking for the
+ // IPHONEOS_DEPLOYMENT_TARGET env var. If it isn't there, we are running
+ // on the simulator.
+ if (!getenv("IPHONEOS_DEPLOYMENT_TARGET")) {
+ if (!getenv("GTM_DISABLE_LEAKS")) {
+ atexit(&RunLeaks);
+ }
+ }
[self runTests];
// Using private call to end our tests
- [[UIApplication sharedApplication] terminate];
+ if (!getenv("GTM_DISABLE_TERMINATION")) {
+ [[UIApplication sharedApplication] terminate];
+ }
}
// Run through all the registered classes and run test methods on any
diff --git a/UnitTesting/GTMNSObject+UnitTesting.m b/UnitTesting/GTMNSObject+UnitTesting.m
index 8e0899d..a722b9e 100644
--- a/UnitTesting/GTMNSObject+UnitTesting.m
+++ b/UnitTesting/GTMNSObject+UnitTesting.m
@@ -26,6 +26,8 @@
#if GTM_IPHONE_SDK
#import <UIKit/UIKit.h>
+#else
+#import <AppKit/AppKit.h>
#endif
NSString *const GTMUnitTestingEncodedObjectNotification = @"GTMUnitTestingEncodedObjectNotification";
diff --git a/UnitTesting/GTMTestTimer.h b/UnitTesting/GTMTestTimer.h
new file mode 100644
index 0000000..200f9b1
--- /dev/null
+++ b/UnitTesting/GTMTestTimer.h
@@ -0,0 +1,125 @@
+//
+// GTMTestTimer.h
+//
+// Copyright 2006-2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import <Foundation/Foundation.h>
+#import "GTMDefines.h"
+#import <mach/mach_time.h>
+
+// GTMTestTimer is done in straight inline C to avoid obj-c calling overhead.
+// It is for doing test timings at very high precision.
+// Test Timers have standard CoreFoundation Retain/Release rules.
+// Test Timers are not thread safe. Test Timers do NOT check their arguments
+// for NULL. You will crash if you pass a NULL argument in.
+
+typedef struct {
+ mach_timebase_info_data_t time_base_info_;
+ bool running_;
+ uint64_t start_;
+ uint64_t split_;
+ uint64_t elapsed_;
+ NSUInteger iterations_;
+ NSUInteger retainCount_;
+} GTMTestTimer;
+
+// Create a test timer
+FOUNDATION_STATIC_INLINE GTMTestTimer *GTMTestTimerCreate(void) {
+ GTMTestTimer *t = calloc(sizeof(GTMTestTimer), 1);
+ if (t) {
+ if (mach_timebase_info(&t->time_base_info_) == KERN_SUCCESS) {
+ t->retainCount_ = 1;
+ } else {
+ // COV_NF_START
+ free(t);
+ t = NULL;
+ // COV_NF_END
+ }
+ }
+ return t;
+}
+
+// Retain a timer
+FOUNDATION_STATIC_INLINE void GTMTestTimerRetain(GTMTestTimer *t) {
+ t->retainCount_ += 1;
+}
+
+// Release a timer. When release count hits zero, we free it.
+FOUNDATION_STATIC_INLINE void GTMTestTimerRelease(GTMTestTimer *t) {
+ t->retainCount_ -= 1;
+ if (t->retainCount_ == 0) {
+ free(t);
+ }
+}
+
+// Starts a timer timing. Specifically starts a new split. If the timer is
+// currently running, it resets the start time of the current split.
+FOUNDATION_STATIC_INLINE void GTMTestTimerStart(GTMTestTimer *t) {
+ t->start_ = mach_absolute_time();
+ t->running_ = true;
+}
+
+// Stops a timer and returns split time (time from last start) in nanoseconds.
+FOUNDATION_STATIC_INLINE uint64_t GTMTestTimerStop(GTMTestTimer *t) {
+ uint64_t now = mach_absolute_time();
+ t->running_ = false;
+ ++t->iterations_;
+ t->split_ = now - t->start_;
+ t->elapsed_ += t->split_;
+ t->start_ = 0;
+ return t->split_;
+}
+
+// returns the current timer elapsed time (combined value of all splits, plus
+// current split if the timer is running) in nanoseconds.
+FOUNDATION_STATIC_INLINE double GTMTestTimerGetNanoseconds(GTMTestTimer *t) {
+ uint64_t total = t->elapsed_;
+ if (t->running_) {
+ total += mach_absolute_time() - t->start_;
+ }
+ return (double)(total * t->time_base_info_.numer
+ / t->time_base_info_.denom);
+}
+
+// Returns the current timer elapsed time (combined value of all splits, plus
+// current split if the timer is running) in seconds.
+FOUNDATION_STATIC_INLINE double GTMTestTimerGetSeconds(GTMTestTimer *t) {
+ return GTMTestTimerGetNanoseconds(t) * 0.000000001;
+}
+
+// Returns the current timer elapsed time (combined value of all splits, plus
+// current split if the timer is running) in milliseconds.
+FOUNDATION_STATIC_INLINE double GTMTestTimerGetMilliseconds(GTMTestTimer *t) {
+ return GTMTestTimerGetNanoseconds(t) * 0.000001;
+}
+
+// Returns the current timer elapsed time (combined value of all splits, plus
+// current split if the timer is running) in microseconds.
+FOUNDATION_STATIC_INLINE double GTMTestTimerGetMicroseconds(GTMTestTimer *t) {
+ return GTMTestTimerGetNanoseconds(t) * 0.001;
+}
+
+// Returns the number of splits (start-stop) cycles recorded.
+// GTMTestTimerGetSeconds()/GTMTestTimerGetIterations() gives you an average
+// of all your splits.
+FOUNDATION_STATIC_INLINE NSUInteger GTMTestTimerGetIterations(GTMTestTimer *t) {
+ return t->iterations_;
+}
+
+// Returns true if the timer is running.
+FOUNDATION_STATIC_INLINE bool GTMTestTimerIsRunning(GTMTestTimer *t) {
+ return t->running_;
+}
diff --git a/UnitTesting/GTMTestTimerTest.m b/UnitTesting/GTMTestTimerTest.m
new file mode 100644
index 0000000..86f9d22
--- /dev/null
+++ b/UnitTesting/GTMTestTimerTest.m
@@ -0,0 +1,56 @@
+//
+// GTMTestTimerTest.m
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+//
+
+#import "GTMSenTestCase.h"
+#import "GTMTestTimer.h"
+
+@interface GTMTestTimerTest : GTMTestCase
+@end
+
+@implementation GTMTestTimerTest
+- (void)testTimer {
+ GTMTestTimer *timer = GTMTestTimerCreate();
+ STAssertNotNULL(timer, nil);
+ GTMTestTimerRetain(timer);
+ GTMTestTimerRelease(timer);
+ STAssertEqualsWithAccuracy(GTMTestTimerGetSeconds(timer), 0.0, 0.0, nil);
+ GTMTestTimerStart(timer);
+ STAssertTrue(GTMTestTimerIsRunning(timer), nil);
+ NSRunLoop *loop = [NSRunLoop currentRunLoop];
+ [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+ GTMTestTimerStop(timer);
+
+ // We use greater than (and an almost absurd less than) because
+ // these tests are very dependant on machine load, and we don't want
+ // automated tests reporting false negatives.
+ STAssertGreaterThan(GTMTestTimerGetSeconds(timer), 0.1, nil);
+ STAssertGreaterThan(GTMTestTimerGetMilliseconds(timer), 100.0,nil);
+ STAssertGreaterThan(GTMTestTimerGetMicroseconds(timer), 100000.0, nil);
+
+ // Check to make sure we're not WAY off the mark (by a factor of 10)
+ STAssertLessThan(GTMTestTimerGetMicroseconds(timer), 1000000.0, nil);
+
+ [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+ GTMTestTimerStart(timer);
+ [loop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
+ STAssertGreaterThan(GTMTestTimerGetSeconds(timer), 0.2, nil);
+ GTMTestTimerStop(timer);
+ STAssertEquals(GTMTestTimerGetIterations(timer), (NSUInteger)2, nil);
+ GTMTestTimerRelease(timer);
+}
+@end
diff --git a/UnitTesting/RunIPhoneUnitTest.sh b/UnitTesting/RunIPhoneUnitTest.sh
index 0089032..1718bda 100755
--- a/UnitTesting/RunIPhoneUnitTest.sh
+++ b/UnitTesting/RunIPhoneUnitTest.sh
@@ -17,6 +17,27 @@
# Runs all unittests through the iPhone simulator. We don't handle running them
# on the device. To run on the device just choose "run".
+# Controlling environment variables:
+#
+# GTM_DISABLE_ZOMBIES -
+# Set to a non-zero value to turn off zombie checks that can interfere with
+# leak checking.
+#
+# GTM_DISABLE_LEAKS -
+# Set to a non-zero value to turn off the leaks check.
+#
+# GTM_DISABLE_TERMINATION
+# Set to a non-zero value so that the app doesn't terminate when it's finished
+# running tests. This is useful when using it with external tools such
+# as Instruments.
+
+ScriptDir=$(dirname $(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,"))
+ScriptName=$(basename "$0")
+ThisScript="${ScriptDir}/${ScriptName}"
+
+GTMXcodeNote() {
+ echo ${ThisScript}:${1}: note: GTM ${2}
+}
if [ "$IPHONEOS_DEPLOYMENT_TARGET" == "" ]; then
# We kill the iPhone simulator because otherwise we run into issues where
@@ -24,22 +45,30 @@ if [ "$IPHONEOS_DEPLOYMENT_TARGET" == "" ]; then
# at this time the iPhone SDK won't allow two simulators running at the same
# time.
/usr/bin/killall "iPhone Simulator"
+
export DYLD_ROOT_PATH="$SDKROOT"
export DYLD_FRAMEWORK_PATH="$CONFIGURATION_BUILD_DIR"
export IPHONE_SIMULATOR_ROOT="$SDKROOT"
export CFFIXED_USER_HOME="$USER_LIBRARY_DIR/Application Support/iPhone Simulator/User"
- # Encourage errors
+ # See http://developer.apple.com/technotes/tn2004/tn2124.html for an
+ # explanation of these environment variables.
+
export MallocScribble=YES
export MallocPreScribble=YES
export MallocGuardEdges=YES
- export CFZombieLevel=3
+ export MallocStackLogging=YES
export NSAutoreleaseFreedObjectCheckEnabled=YES
- export NSZombieEnabled=YES
export OBJC_DEBUG_FRAGILE_SUPERCLASSES=YES
+ if [ ! $GTM_DISABLE_ZOMBIES ]; then
+ GTMXcodeNote ${LINENO} "Enabling zombies"
+ export CFZombieLevel=3
+ export NSZombieEnabled=YES
+ fi
+
"$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -RegisterForSystemEvents
else
- echo "note: Skipping running of unittests for device build."
+ GTMXcodeNote ${LINENO} "Skipping running of unittests for device build."
fi
exit 0
diff --git a/UnitTesting/RunMacOSUnitTests.sh b/UnitTesting/RunMacOSUnitTests.sh
index 45d0afc..5c36a79 100755
--- a/UnitTesting/RunMacOSUnitTests.sh
+++ b/UnitTesting/RunMacOSUnitTests.sh
@@ -19,21 +19,46 @@
# See http://developer.apple.com/technotes/tn2004/tn2124.html for details.
#
-export MallocScribble=YES
-export MallocPreScribble=YES
-export MallocGuardEdges=YES
-# CFZombieLevel disabled because it doesn't play well with the
-# security framework
-# export CFZombieLevel=3
-export NSAutoreleaseFreedObjectCheckEnabled=YES
-export NSZombieEnabled=YES
-export OBJC_DEBUG_FRAGILE_SUPERCLASSES=YES
+# Controlling environment variables:
+#
+# GTM_NO_MEMORY_STRESS -
+# Set to zero to prevent the setting of system library/framework debugging
+# environment variables that help find problems in code. See
+# http://developer.apple.com/technotes/tn2004/tn2124.html
+# for details.
+# GTM_NO_DEBUG_FRAMEWORKS -
+# Set to zero to prevent the use of the debug versions of system
+# libraries/frameworks if you have them installed on your system. The frameworks
+# can be found at http://connect.apple.com > Downloads > Developer Tools
+# (https://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?bundleID=19915)
+
+ScriptDir=$(dirname $(echo $0 | sed -e "s,^\([^/]\),$(pwd)/\1,"))
+ScriptName=$(basename "$0")
+ThisScript="${ScriptDir}/${ScriptName}"
+
+GTMXcodeNote() {
+ echo ${ThisScript}:${1}: note: GTM ${2}
+}
+
+# Jack up some memory stress so we can catch more bugs.
+if [ ! $GTM_NO_MEMORY_STRESS ]; then
+ GTMXcodeNote ${LINENO} "Enabling memory stressing"
+ export MallocScribble=YES
+ export MallocPreScribble=YES
+ export MallocGuardEdges=YES
+ # CFZombieLevel disabled because it doesn't play well with the
+ # security framework
+ # export CFZombieLevel=3
+ export NSAutoreleaseFreedObjectCheckEnabled=YES
+ export NSZombieEnabled=YES
+ export OBJC_DEBUG_FRAGILE_SUPERCLASSES=YES
+fi
# If we have debug libraries on the machine, we'll use them
# unless a target has specifically turned them off
if [ ! $GTM_NO_DEBUG_FRAMEWORKS ]; then
if [ -f "/System/Library/Frameworks/CoreFoundation.framework/Versions/Current/CoreFoundation_debug" ]; then
- echo ---- Using _debug frameworks ----
+ GTMXcodeNote ${LINENO} "Using _debug frameworks"
export DYLD_IMAGE_SUFFIX=_debug
fi
fi
diff --git a/XcodeConfig/Project/DebugiPhone.xcconfig b/XcodeConfig/Project/DebugiPhone.xcconfig
index 4af17bd..6067fff 100644
--- a/XcodeConfig/Project/DebugiPhone.xcconfig
+++ b/XcodeConfig/Project/DebugiPhone.xcconfig
@@ -1,10 +1,10 @@
//
-// DebugiPhoneSimulator.xcconfig
+// DebugiPhone.xcconfig
//
// Xcode configuration file for building a Debug configuration of a project
// for iPhone.
//
-// Copyright 2006-2008 Google Inc.
+// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -19,16 +19,8 @@
// the License.
//
-// This is a _Configuration_ Xcode config file for use in the "Based on" popup
-// of the project configuration editor. Do _not_ use this as the config base
-// and individual Xcode target, there are other configuration files for that
-// purpose.
-
-// Pull in the general settings
-#include "../subconfig/General.xcconfig"
+// This file is deprecated, please use the version specific one instead.
+//
-// iPhone settings
-#include "../subconfig/iPhone.xcconfig"
+#include "DebugiPhone20.xcconfig"
-// Release settings
-#include "../subconfig/Debug.xcconfig"
diff --git a/XcodeConfig/Project/DebugiPhone20.xcconfig b/XcodeConfig/Project/DebugiPhone20.xcconfig
new file mode 100644
index 0000000..1f08ee4
--- /dev/null
+++ b/XcodeConfig/Project/DebugiPhone20.xcconfig
@@ -0,0 +1,34 @@
+//
+// DebugiPhone20.xcconfig
+//
+// Xcode configuration file for building a Debug configuration of a project
+// for iPhone OS 2.0.
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+//
+// This is a _Configuration_ Xcode config file for use in the "Based on" popup
+// of the project configuration editor. Do _not_ use this as the config base
+// and individual Xcode target, there are other configuration files for that
+// purpose.
+
+// Pull in the general settings
+#include "../subconfig/General.xcconfig"
+
+// iPhone settings
+#include "../subconfig/iPhone20.xcconfig"
+
+// Release settings
+#include "../subconfig/Debug.xcconfig"
diff --git a/XcodeConfig/Project/DebugiPhone21.xcconfig b/XcodeConfig/Project/DebugiPhone21.xcconfig
new file mode 100644
index 0000000..b718cfa
--- /dev/null
+++ b/XcodeConfig/Project/DebugiPhone21.xcconfig
@@ -0,0 +1,34 @@
+//
+// DebugiPhone21.xcconfig
+//
+// Xcode configuration file for building a Debug configuration of a project
+// for iPhone OS 2.1.
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+//
+// This is a _Configuration_ Xcode config file for use in the "Based on" popup
+// of the project configuration editor. Do _not_ use this as the config base
+// and individual Xcode target, there are other configuration files for that
+// purpose.
+
+// Pull in the general settings
+#include "../subconfig/General.xcconfig"
+
+// iPhone settings
+#include "../subconfig/iPhone21.xcconfig"
+
+// Release settings
+#include "../subconfig/Debug.xcconfig"
diff --git a/XcodeConfig/Project/ReleaseiPhone.xcconfig b/XcodeConfig/Project/ReleaseiPhone.xcconfig
index 1473a5a..49c1141 100644
--- a/XcodeConfig/Project/ReleaseiPhone.xcconfig
+++ b/XcodeConfig/Project/ReleaseiPhone.xcconfig
@@ -1,10 +1,10 @@
//
-// ReleaseAspenSimulator.xcconfig
+// ReleaseiPhone.xcconfig
//
// Xcode configuration file for building a Release configuration of a project
// for iPhone.
//
-// Copyright 2006-2008 Google Inc.
+// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
@@ -19,16 +19,8 @@
// the License.
//
-// This is a _Configuration_ Xcode config file for use in the "Based on" popup
-// of the project configuration editor. Do _not_ use this as the config base
-// and individual Xcode target, there are other configuration files for that
-// purpose.
-
-// Pull in the general settings
-#include "../subconfig/General.xcconfig"
+// This file is deprecated, please use the version specific one instead.
+//
-// iPhone Settings.
-#include "../subconfig/iPhone.xcconfig"
+#include "ReleaseiPhone20.xcconfig"
-// Release settings
-#include "../subconfig/Release.xcconfig"
diff --git a/XcodeConfig/Project/ReleaseiPhone20.xcconfig b/XcodeConfig/Project/ReleaseiPhone20.xcconfig
new file mode 100644
index 0000000..16895c5
--- /dev/null
+++ b/XcodeConfig/Project/ReleaseiPhone20.xcconfig
@@ -0,0 +1,34 @@
+//
+// ReleaseiPhone20.xcconfig
+//
+// Xcode configuration file for building a Release configuration of a project
+// for iPhone OS 2.0.
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+//
+// This is a _Configuration_ Xcode config file for use in the "Based on" popup
+// of the project configuration editor. Do _not_ use this as the config base
+// and individual Xcode target, there are other configuration files for that
+// purpose.
+
+// Pull in the general settings
+#include "../subconfig/General.xcconfig"
+
+// iPhone Settings.
+#include "../subconfig/iPhone20.xcconfig"
+
+// Release settings
+#include "../subconfig/Release.xcconfig"
diff --git a/XcodeConfig/Project/ReleaseiPhone21.xcconfig b/XcodeConfig/Project/ReleaseiPhone21.xcconfig
new file mode 100644
index 0000000..4ea90d6
--- /dev/null
+++ b/XcodeConfig/Project/ReleaseiPhone21.xcconfig
@@ -0,0 +1,34 @@
+//
+// ReleaseiPhone21.xcconfig
+//
+// Xcode configuration file for building a Release configuration of a project
+// for iPhone OS 2.1.
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+//
+// This is a _Configuration_ Xcode config file for use in the "Based on" popup
+// of the project configuration editor. Do _not_ use this as the config base
+// and individual Xcode target, there are other configuration files for that
+// purpose.
+
+// Pull in the general settings
+#include "../subconfig/General.xcconfig"
+
+// iPhone Settings.
+#include "../subconfig/iPhone21.xcconfig"
+
+// Release settings
+#include "../subconfig/Release.xcconfig"
diff --git a/XcodeConfig/subconfig/General.xcconfig b/XcodeConfig/subconfig/General.xcconfig
index 6031f46..114b718 100644
--- a/XcodeConfig/subconfig/General.xcconfig
+++ b/XcodeConfig/subconfig/General.xcconfig
@@ -21,7 +21,9 @@
// NOTE: as of Xcode 3.1, for iPhone development, the two SDKs you can match are:
// SDK_NAME iphoneos2.0
+// SDK_NAME iphoneos2.1
// SDK_NAME iphonesimulator2.0
+// SDK_NAME iphonesimulator2.1
// for Mac OS developement, the values are:
// SDK_NAME macosx10.4
// SDK_NAME macosx10.5
diff --git a/XcodeConfig/subconfig/iPhone.xcconfig b/XcodeConfig/subconfig/iPhone20.xcconfig
index 0948db8..fea781b 100644
--- a/XcodeConfig/subconfig/iPhone.xcconfig
+++ b/XcodeConfig/subconfig/iPhone20.xcconfig
@@ -1,9 +1,9 @@
//
-// iPhone.xcconfig
+// iPhone20.xcconfig
//
-// Xcode configuration file for building a Debug target on iPhone
+// Xcode configuration file for building a Debug target on iPhone OS 2.0
//
-// Copyright 2006-2008 Google Inc.
+// Copyright 2008 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not
// use this file except in compliance with the License. You may obtain a copy
diff --git a/XcodeConfig/subconfig/iPhone21.xcconfig b/XcodeConfig/subconfig/iPhone21.xcconfig
new file mode 100644
index 0000000..6265000
--- /dev/null
+++ b/XcodeConfig/subconfig/iPhone21.xcconfig
@@ -0,0 +1,26 @@
+//
+// iPhone21.xcconfig
+//
+// Xcode configuration file for building a Debug target on iPhone OS 2.1
+//
+// Copyright 2008 Google Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License"); you may not
+// use this file except in compliance with the License. You may obtain a copy
+// of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations under
+// the License.
+
+// Code signing. Should be overridden if releasing
+CODE_SIGN_IDENTITY[sdk=iphoneos*] = iPhone Developer
+
+// Default SDK and minimum OS version is the iphone SDK.
+SDKROOT = iphoneos2.1
+MACOSX_DEPLOYMENT_TARGET = 10.5
+GCC_VERSION = 4.0
diff --git a/iPhone/GTMABAddressBook.m b/iPhone/GTMABAddressBook.m
index 0c54364..c06b511 100644
--- a/iPhone/GTMABAddressBook.m
+++ b/iPhone/GTMABAddressBook.m
@@ -189,6 +189,7 @@ typedef struct {
- (id)initWithRecord:(ABRecordRef)record {
if ((self = [super init])) {
if ([self class] == [GTMABRecord class]) {
+ [self autorelease];
[self doesNotRecognizeSelector:_cmd];
}
if (!record) {
@@ -509,6 +510,8 @@ typedef struct {
@implementation GTMABMultiValue
- (id)init {
+ // Call super init and release so we don't leak
+ [[super init] autorelease];
[self doesNotRecognizeSelector:_cmd];
return nil; // COV_NF_LINE
}
diff --git a/iPhone/GTMABAddressBookTest.m b/iPhone/GTMABAddressBookTest.m
index 3ecb796..56106a9 100644
--- a/iPhone/GTMABAddressBookTest.m
+++ b/iPhone/GTMABAddressBookTest.m
@@ -534,24 +534,31 @@
thirdRetainCount,
@"Testing type %d, %@", type, val);
+ id oldVal = val;
val = (id)ABMultiValueCopyValueAtIndex(ref, 0);
NSUInteger fourthRetainCount = [val retainCount];
- if (type == kABIntegerPropertyType
- || type == kABRealPropertyType
- || type == kABDictionaryPropertyType) {
- // We are verifying that yes indeed 6208390 is still broken
- STAssertEquals(fourthRetainCount,
- thirdRetainCount,
- @"Testing type %d, %@. If you see this error it may "
- @"be time to update the code to change retain behaviors"
- @"with this os version", type, val);
+
+ // kABDictionaryPropertyTypes appear to do an actual copy, so the retain
+ // count checking trick won't work. We only check the retain count if
+ // we didn't get a new version.
+ if (val == oldVal) {
+ if (type == kABIntegerPropertyType
+ || type == kABRealPropertyType) {
+ // We are verifying that yes indeed 6208390 is still broken
+ STAssertEquals(fourthRetainCount,
+ thirdRetainCount,
+ @"Testing type %d, %@. If you see this error it may "
+ @"be time to update the code to change retain behaviors"
+ @"with this os version", type, val);
+ } else {
+ STAssertEquals(fourthRetainCount,
+ thirdRetainCount + 1,
+ @"Testing type %d, %@", type, val);
+ [val release];
+ }
} else {
- STAssertEquals(fourthRetainCount,
- thirdRetainCount + 1,
- @"Testing type %d, %@", type, val);
[val release];
}
-
CFRelease(ref);
}
}