diff options
-rw-r--r-- | AppKit/GTMHotKeyTextField.m | 2 | ||||
-rw-r--r-- | AppKit/GTMNSBezierPath+CGPath.h | 4 | ||||
-rw-r--r-- | AppKit/GTMNSBezierPath+CGPath.m | 7 | ||||
-rw-r--r-- | AppKit/GTMNSBezierPath+CGPathTest.m | 5 | ||||
-rw-r--r-- | AppKit/GTMNSBezierPath+Shading.m | 14 | ||||
-rw-r--r-- | Foundation/GTMObjC2RuntimeTest.m | 23 | ||||
-rw-r--r-- | Foundation/GTMSystemVersion.m | 2 | ||||
-rw-r--r-- | Foundation/GTMTransientRootProxyTest.m | 28 | ||||
-rw-r--r-- | ReleaseNotes.txt | 10 | ||||
-rw-r--r-- | UnitTesting/GTMAppKit+UnitTesting.m | 31 | ||||
-rw-r--r-- | UnitTesting/GTMCALayer+UnitTesting.m | 9 | ||||
-rw-r--r-- | UnitTesting/GTMNSObject+UnitTesting.h | 38 | ||||
-rw-r--r-- | UnitTesting/GTMNSObject+UnitTesting.m | 238 | ||||
-rw-r--r-- | UnitTesting/GTMUIKit+UnitTesting.h | 12 | ||||
-rw-r--r-- | UnitTesting/GTMUIKit+UnitTesting.m | 10 | ||||
-rw-r--r-- | UnitTesting/GTMUnitTestingTest.m | 2 |
16 files changed, 222 insertions, 213 deletions
diff --git a/AppKit/GTMHotKeyTextField.m b/AppKit/GTMHotKeyTextField.m index 6410041..6573743 100644 --- a/AppKit/GTMHotKeyTextField.m +++ b/AppKit/GTMHotKeyTextField.m @@ -209,7 +209,7 @@ static CFStringRef kGTM_TISPropertyUnicodeKeyLayoutData = NULL; #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 -- (int)integerValue { +- (NSInteger)integerValue { // Defeating NSControl _GTMDevAssert(NO, @"Hot key fields don't take numbers."); diff --git a/AppKit/GTMNSBezierPath+CGPath.h b/AppKit/GTMNSBezierPath+CGPath.h index 3349142..a1b022e 100644 --- a/AppKit/GTMNSBezierPath+CGPath.h +++ b/AppKit/GTMNSBezierPath+CGPath.h @@ -26,8 +26,8 @@ // Args: // // Returns: -// Converted CGPathRef. Must be released by client (CGPathRelease). +// Converted autoreleased CGPathRef. // nil if failure. -- (CGPathRef)gtm_createCGPath; +- (CGPathRef)gtm_CGPath; @end diff --git a/AppKit/GTMNSBezierPath+CGPath.m b/AppKit/GTMNSBezierPath+CGPath.m index 656a139..3624d9e 100644 --- a/AppKit/GTMNSBezierPath+CGPath.m +++ b/AppKit/GTMNSBezierPath+CGPath.m @@ -19,6 +19,7 @@ // #import "GTMNSBezierPath+CGPath.h" #import "GTMDefines.h" +#import "GTMGarbageCollection.h" @implementation NSBezierPath (GTMBezierPathCGPathAdditions) @@ -27,9 +28,9 @@ // Args: // // Returns: -// Converted CGPathRef. Must be released by client (CGPathRelease). +// Converted CGPathRef. // nil if failure. -- (CGPathRef)gtm_createCGPath { +- (CGPathRef)gtm_CGPath { CGMutablePathRef thePath = CGPathCreateMutable(); if (!thePath) return nil; @@ -63,7 +64,7 @@ break; // COV_NF_END }; } - return thePath; + return (CGPathRef)GTMCFAutorelease(thePath); } @end diff --git a/AppKit/GTMNSBezierPath+CGPathTest.m b/AppKit/GTMNSBezierPath+CGPathTest.m index eb86353..3c99a19 100644 --- a/AppKit/GTMNSBezierPath+CGPathTest.m +++ b/AppKit/GTMNSBezierPath+CGPathTest.m @@ -28,7 +28,7 @@ @implementation GTMNSBezierPath_CGPathTest -- (void)testCreateCGPath { +- (void)testCGPath { GTMAssertDrawingEqualToImageNamed(self, NSMakeSize(100, 100), @"GTMNSBezierPath+CGPathTest", @@ -62,7 +62,7 @@ // test close [thePath closePath]; - CGPathRef cgPath = [thePath gtm_createCGPath]; + CGPathRef cgPath = [thePath gtm_CGPath]; STAssertNotNULL(cgPath, @"Nil CGPath"); CGContextRef cgContext = [[NSGraphicsContext currentContext] graphicsPort]; @@ -70,7 +70,6 @@ CGContextAddPath(cgContext, cgPath); CGContextStrokePath(cgContext); - CGPathRelease(cgPath); } @end diff --git a/AppKit/GTMNSBezierPath+Shading.m b/AppKit/GTMNSBezierPath+Shading.m index f75876f..d4c1ddd 100644 --- a/AppKit/GTMNSBezierPath+Shading.m +++ b/AppKit/GTMNSBezierPath+Shading.m @@ -154,19 +154,18 @@ @implementation NSBezierPath (GTMBezierPathShadingAdditions) -GTM_METHOD_CHECK(NSBezierPath, gtm_createCGPath); +GTM_METHOD_CHECK(NSBezierPath, gtm_CGPath); - (void)gtm_strokeAxiallyFrom:(NSPoint)fromPoint to:(NSPoint)toPoint extendingStart:(BOOL)extendingStart extendingEnd:(BOOL)extendingEnd shading:(id<GTMShading>)shading { - CGPathRef thePath = [self gtm_createCGPath]; + CGPathRef thePath = [self gtm_CGPath]; if (nil != thePath) { [self gtm_fillCGPath:thePath axially:YES asStroke:YES from:fromPoint fromRadius:(CGFloat)0.0 to:toPoint toRadius:(CGFloat)0.0 extendingStart:extendingStart extendingEnd:extendingEnd shading:shading]; - CGPathRelease(thePath); } } @@ -175,14 +174,13 @@ GTM_METHOD_CHECK(NSBezierPath, gtm_createCGPath); to:(NSPoint)toPoint toRadius:(CGFloat)toRadius extendingStart:(BOOL)extendingStart extendingEnd:(BOOL)extendingEnd shading:(id<GTMShading>)shading { - CGPathRef thePath = [self gtm_createCGPath]; + CGPathRef thePath = [self gtm_CGPath]; if (nil != thePath) { [self gtm_fillCGPath:thePath axially:NO asStroke:YES from:fromPoint fromRadius:fromRadius to:toPoint toRadius:toRadius extendingStart:extendingStart extendingEnd:extendingEnd shading:shading]; - CGPathRelease(thePath); } } @@ -190,14 +188,13 @@ GTM_METHOD_CHECK(NSBezierPath, gtm_createCGPath); - (void)gtm_fillAxiallyFrom:(NSPoint)fromPoint to:(NSPoint)toPoint extendingStart:(BOOL)extendingStart extendingEnd:(BOOL)extendingEnd shading:(id<GTMShading>)shading { - CGPathRef thePath = [self gtm_createCGPath]; + CGPathRef thePath = [self gtm_CGPath]; if (nil != thePath) { [self gtm_fillCGPath:thePath axially:YES asStroke:NO from:fromPoint fromRadius:(CGFloat)0.0 to:toPoint toRadius:(CGFloat)0.0 extendingStart:extendingStart extendingEnd:extendingEnd shading:shading]; - CGPathRelease(thePath); } } @@ -206,14 +203,13 @@ GTM_METHOD_CHECK(NSBezierPath, gtm_createCGPath); to:(NSPoint)toPoint toRadius:(CGFloat)toRadius extendingStart:(BOOL)extendingStart extendingEnd:(BOOL)extendingEnd shading:(id<GTMShading>)shading { - CGPathRef thePath = [self gtm_createCGPath]; + CGPathRef thePath = [self gtm_CGPath]; if (nil != thePath) { [self gtm_fillCGPath:thePath axially:NO asStroke:NO from:fromPoint fromRadius:fromRadius to:toPoint toRadius:toRadius extendingStart:extendingStart extendingEnd:extendingEnd shading:shading]; - CGPathRelease(thePath); } } diff --git a/Foundation/GTMObjC2RuntimeTest.m b/Foundation/GTMObjC2RuntimeTest.m index d0ce4f7..7344a0f 100644 --- a/Foundation/GTMObjC2RuntimeTest.m +++ b/Foundation/GTMObjC2RuntimeTest.m @@ -78,6 +78,20 @@ AT_REQUIRED @end @implementation GTMObjC2NotificationWatcher +- (id)init { + if ((self = [super init])) { + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + // We release ourselves when we are notified. + [self retain]; + [nc addObserver:self + selector:@selector(startedTest:) + name:SenTestSuiteDidStartNotification + object:nil]; + + } + return self; +} + - (void)startedTest:(NSNotification *)notification { // Logs if we are testing on Tiger or Leopard runtime. NSString *testName = [(SenTest*)[[notification object] test] name]; @@ -101,14 +115,7 @@ AT_REQUIRED + (void)initialize { // This allows us to track which runtime we are actually testing. - NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - - // Watcher is released when it is notified. - GTMObjC2NotificationWatcher *watcher = [[GTMObjC2NotificationWatcher alloc] init]; - [nc addObserver:watcher - selector:@selector(startedTest:) - name:SenTestSuiteDidStartNotification - object:nil]; + [[[GTMObjC2NotificationWatcher alloc] init] autorelease]; } - (void)setUp { diff --git a/Foundation/GTMSystemVersion.m b/Foundation/GTMSystemVersion.m index be5d7c3..eb255a6 100644 --- a/Foundation/GTMSystemVersion.m +++ b/Foundation/GTMSystemVersion.m @@ -19,7 +19,7 @@ #import "GTMSystemVersion.h" #import "GTMGarbageCollection.h" #if GTM_MACOS_SDK -#import <Carbon/Carbon.h> +#import <CoreServices/CoreServices.h> #endif static SInt32 sGTMSystemVersionMajor = 0; diff --git a/Foundation/GTMTransientRootProxyTest.m b/Foundation/GTMTransientRootProxyTest.m index ac18432..e4e7017 100644 --- a/Foundation/GTMTransientRootProxyTest.m +++ b/Foundation/GTMTransientRootProxyTest.m @@ -24,7 +24,7 @@ #define kServerShuttingDownNotification @"serverShuttingDown" // === Start off declaring some auxillary data structures === -static NSString *const kTestServerName = @"test"; +static NSString *const kTestServerName = @"gtm_test_server"; // The @protocol that we'll use for testing with. @protocol DOTestProtocol @@ -40,7 +40,7 @@ static NSString *const kTestServerName = @"test"; @private BOOL quit_; } -- (void)runThread:(id)ignore; +- (void)runThread:(NSString *)serverName; - (void)shutdownServer; @end @@ -54,7 +54,7 @@ static NSString *const kTestServerName = @"test"; return returnValue; } -- (void)runThread:(id)ignore { +- (void)runThread:(NSString *)serverName { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; @@ -62,9 +62,9 @@ static NSString *const kTestServerName = @"test"; NSConnection *conn = [NSConnection defaultConnection]; [conn setRootObject:self]; - if (![conn registerName:kTestServerName]) { + if (![conn registerName:serverName]) { _GTMDevLog(@"Failed to register DO root object with name '%@'", - kTestServerName); + serverName); // We hit an error, we are shutting down. quit_ = YES; } @@ -134,16 +134,20 @@ static NSString *const kTestServerName = @"test"; object:nil]; serverOffline_ = NO; - // Setup our server. + // Setup our server and create a unqiue server name every time we run + NSTimeInterval timeStamp = [[NSDate date] timeIntervalSinceReferenceDate]; + NSString *serverName = + [NSString stringWithFormat:@"%@_%f", kTestServerName, timeStamp]; + server_ = [[[DOTestServer alloc] init] autorelease]; [NSThread detachNewThreadSelector:@selector(runThread:) toTarget:server_ - withObject:nil]; + withObject:serverName]; // Sleep for 1 second to give the new thread time to set stuff up [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1]]; GTMTransientRootProxy<DOTestProtocol> *proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:kTestServerName + [GTMTransientRootProxy rootProxyWithRegisteredName:serverName host:nil protocol:@protocol(DOTestProtocol) requestTimeout:kDefaultTimeout @@ -156,7 +160,7 @@ static NSString *const kTestServerName = @"test"; // Redo the *exact* same test to make sure we can have multiple instances // in the same app. proxy = - [GTMTransientRootProxy rootProxyWithRegisteredName:kTestServerName + [GTMTransientRootProxy rootProxyWithRegisteredName:serverName host:nil protocol:@protocol(DOTestProtocol) requestTimeout:kDefaultTimeout @@ -169,7 +173,7 @@ static NSString *const kTestServerName = @"test"; // the server again. GTMRootProxyCatchAll<DOTestProtocol> *catchProxy = - [GTMRootProxyCatchAll rootProxyWithRegisteredName:kTestServerName + [GTMRootProxyCatchAll rootProxyWithRegisteredName:serverName host:nil protocol:@protocol(DOTestProtocol) requestTimeout:kDefaultTimeout @@ -209,6 +213,10 @@ static NSString *const kTestServerName = @"test"; [[NSRunLoop currentRunLoop] runUntilDate:runUntil]; } + // The server did not shutdown and we want to capture this as an error + STAssertTrue([self serverStatus], @"The server did not shutdown gracefully " + @"before the timeout."); + [pool drain]; } diff --git a/ReleaseNotes.txt b/ReleaseNotes.txt index 4b87e72..96fb3ce 100644 --- a/ReleaseNotes.txt +++ b/ReleaseNotes.txt @@ -243,6 +243,16 @@ Changes since 1.5.1 maintaing them, we've dropped them and point folks at the gdata versions which can be used independent of the rest of GData. +- Changed gtm_createCGPath to gtm_cgPath in GTMNSBezier+CGPath. The path + returned is now autoreleased so you don't need to worry about releasing it. + +- Made some changes to the GTMNSObject+UnitTesting APIs. Specifically renamed + gtm_createUnitTestImage to gtm_unitTestImage. The value it returns is now + autoreleased, so no need to release it. Also change + gtm_createUnitTestBitmapOfSize:withData: to a C function. + +- Cleaned up GTM so that it passes the Clang checker without any warnings. + Release 1.5.1 Changes since 1.5.0 diff --git a/UnitTesting/GTMAppKit+UnitTesting.m b/UnitTesting/GTMAppKit+UnitTesting.m index 23c44e3..c35d07d 100644 --- a/UnitTesting/GTMAppKit+UnitTesting.m +++ b/UnitTesting/GTMAppKit+UnitTesting.m @@ -22,6 +22,7 @@ #import "GTMAppKit+UnitTesting.h" #import "GTMGeometryUtils.h" #import "GTMMethodCheck.h" +#import "GTMGarbageCollection.h" #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4 #define ENCODE_NSINTEGER(coder, i, key) [(coder) encodeInt:(i) forKey:(key)] @@ -62,8 +63,8 @@ GTM_METHOD_CHECK(NSObject, gtm_unitTestEncodeState:); @implementation NSWindow (GMUnitTestingAdditions) -- (CGImageRef)gtm_createUnitTestImage { - return [[[self contentView] superview] gtm_createUnitTestImage]; +- (CGImageRef)gtm_unitTestImage { + return [[[self contentView] superview] gtm_unitTestImage]; } - (void)gtm_unitTestEncodeState:(NSCoder*)inCoder { @@ -143,14 +144,15 @@ GTM_METHOD_CHECK(NSObject, gtm_unitTestEncodeState:); [inCoder encodeObject:[self name] forKey:@"ImageName"]; } -- (CGImageRef)gtm_createUnitTestImage { +- (CGImageRef)gtm_unitTestImage { // Create up a context NSSize size = [self size]; NSRect rect = GTMNSRectOfSize(size); - CGContextRef contextRef = [self gtm_createUnitTestBitmapContextOfSize:GTMNSSizeToCGSize(size) - data:NULL]; - NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithGraphicsPort:contextRef - flipped:NO]; + CGSize cgSize = GTMNSSizeToCGSize(size); + CGContextRef contextRef = GTMCreateUnitTestBitmapContextOfSizeWithData(cgSize, + NULL); + NSGraphicsContext *bitmapContext + = [NSGraphicsContext graphicsContextWithGraphicsPort:contextRef flipped:NO]; _GTMDevAssert(bitmapContext, @"Couldn't create ns bitmap context"); [NSGraphicsContext saveGraphicsState]; @@ -160,7 +162,7 @@ GTM_METHOD_CHECK(NSObject, gtm_unitTestEncodeState:); CGImageRef image = CGBitmapContextCreateImage(contextRef); CFRelease(contextRef); [NSGraphicsContext restoreGraphicsState]; - return image; + return (CGImageRef)GTMCFAutorelease(image); } @end @@ -279,13 +281,14 @@ GTM_METHOD_CHECK(NSObject, gtm_unitTestEncodeState:); // // Returns: // an image of the object -- (CGImageRef)gtm_createUnitTestImage { +- (CGImageRef)gtm_unitTestImage { // Create up a context NSRect bounds = [self bounds]; - CGContextRef contextRef = [self gtm_createUnitTestBitmapContextOfSize:GTMNSSizeToCGSize(bounds.size) - data:NULL]; - NSGraphicsContext *bitmapContext = [NSGraphicsContext graphicsContextWithGraphicsPort:contextRef - flipped:NO]; + CGSize cgSize = GTMNSSizeToCGSize(bounds.size); + CGContextRef contextRef = GTMCreateUnitTestBitmapContextOfSizeWithData(cgSize, + NULL); + NSGraphicsContext *bitmapContext + = [NSGraphicsContext graphicsContextWithGraphicsPort:contextRef flipped:NO]; _GTMDevAssert(bitmapContext, @"Couldn't create ns bitmap context"); // Save our state and turn off font smoothing and antialias. @@ -296,7 +299,7 @@ GTM_METHOD_CHECK(NSObject, gtm_unitTestEncodeState:); CGImageRef image = CGBitmapContextCreateImage(contextRef); CFRelease(contextRef); - return image; + return (CGImageRef)GTMCFAutorelease(image); } // Returns whether gtm_unitTestEncodeState should recurse into subviews diff --git a/UnitTesting/GTMCALayer+UnitTesting.m b/UnitTesting/GTMCALayer+UnitTesting.m index 355f956..3ffa209 100644 --- a/UnitTesting/GTMCALayer+UnitTesting.m +++ b/UnitTesting/GTMCALayer+UnitTesting.m @@ -21,6 +21,7 @@ // #import "GTMCALayer+UnitTesting.h" +#import "GTMGarbageCollection.h" @implementation CALayer (GTMUnitTestingAdditions) @@ -33,11 +34,11 @@ // // Returns: // an image of the object -- (CGImageRef)gtm_createUnitTestImage { +- (CGImageRef)gtm_unitTestImage { CGRect bounds = [self bounds]; CGSize size = CGSizeMake(CGRectGetWidth(bounds), CGRectGetHeight(bounds)); - CGContextRef context = [self gtm_createUnitTestBitmapContextOfSize:size - data:NULL]; + CGContextRef context = GTMCreateUnitTestBitmapContextOfSizeWithData(size, + NULL); _GTMDevAssert(context, @"Couldn't create context"); // iPhone renders are flipped @@ -48,7 +49,7 @@ [self renderInContext:context]; CGImageRef image = CGBitmapContextCreateImage(context); CFRelease(context); - return image; + return (CGImageRef)GTMCFAutorelease(image); } // Encodes the state of an object in a manner suitable for comparing diff --git a/UnitTesting/GTMNSObject+UnitTesting.h b/UnitTesting/GTMNSObject+UnitTesting.h index 57b53bf..37eae5b 100644 --- a/UnitTesting/GTMNSObject+UnitTesting.h +++ b/UnitTesting/GTMNSObject+UnitTesting.h @@ -125,6 +125,19 @@ do { \ GTMAssertObjectStateEqualToStateNamed(a1, a2, description, ##__VA_ARGS__); \ } while (0) +// Create a CGBitmapContextRef appropriate for using in creating a unit test +// image. If data is non-NULL, returns the buffer that the bitmap is +// using for it's underlying storage. You must free this buffer using +// free. If data is NULL, uses it's own internal storage. +// Defined as a C function instead of an obj-c method because you have to +// release the CGContextRef that is returned. +// +// Returns: +// an CGContextRef of the object. Caller must release + +CGContextRef GTMCreateUnitTestBitmapContextOfSizeWithData(CGSize size, + unsigned char **data); + // GTMUnitTestingImaging protocol is for objects which need to save their // image for using with the unit testing categories @protocol GTMUnitTestingImaging @@ -132,8 +145,8 @@ do { \ // comparing against a master image. // // Returns: -// an CGImageRef of the object. Caller must release -- (CGImageRef)gtm_createUnitTestImage; +// an CGImageRef of the object. +- (CGImageRef)gtm_unitTestImage; @end // GTMUnitTestingEncoding protocol is for objects which need to save their @@ -176,23 +189,6 @@ do { \ + (void)gtm_setUnitTestSaveToDirectory:(NSString*)path; + (NSString *)gtm_getUnitTestSaveToDirectory; -// Create a CGColorSpaceRef appropriate for using in creating a unit test image -// iPhone uses device colorspace. -// Returns: -// an CGColorSpaceRef of the object. Caller must release -- (CGColorSpaceRef)gtm_createUnitTestColorspace; - -// Create a CGBitmapContextRef appropriate for using in creating a unit test -// image. If data is non-NULL, returns the buffer that the bitmap is -// using for it's underlying storage. You must free this buffer using -// free. If data is NULL, uses it's own internal storage. -// In either case, it will be filled with transparency. -// -// Returns: -// an CGContextRef of the object. Caller must release -- (CGContextRef)gtm_createUnitTestBitmapContextOfSize:(CGSize)size - data:(unsigned char **)data; - // Checks to see that system settings are valid for doing an image comparison. // Most of these are set by our unit test app. See the unit test app main.m // for details. @@ -283,8 +279,8 @@ do { \ // path: The path to the image. // // Returns: -// A CGImageRef that you own, or nil if no image at path -- (CGImageRef)gtm_createImageUsingPath:(NSString*)path; +// An autoreleased CGImageRef own, or nil if no image at path +- (CGImageRef)gtm_imageWithContentsOfFile:(NSString*)path; // Generates a path for a image in the save directory, which is desktop // by default. diff --git a/UnitTesting/GTMNSObject+UnitTesting.m b/UnitTesting/GTMNSObject+UnitTesting.m index b30d4d8..cc6a7ea 100644 --- a/UnitTesting/GTMNSObject+UnitTesting.m +++ b/UnitTesting/GTMNSObject+UnitTesting.m @@ -28,7 +28,8 @@ #import <AppKit/AppKit.h> #endif -NSString *const GTMUnitTestingEncodedObjectNotification = @"GTMUnitTestingEncodedObjectNotification"; +NSString *const GTMUnitTestingEncodedObjectNotification + = @"GTMUnitTestingEncodedObjectNotification"; NSString *const GTMUnitTestingEncoderKey = @"GTMUnitTestingEncoderKey"; #if GTM_IPHONE_SDK @@ -57,7 +58,7 @@ BOOL GTMIsObjectImageEqualToImageNamed(id object, if (error) { *error = nil; } - BOOL isGood = [object respondsToSelector:@selector(gtm_createUnitTestImage)]; + BOOL isGood = [object respondsToSelector:@selector(gtm_unitTestImage)]; if (isGood) { if ([object gtm_areSystemSettingsValidForDoingImage]) { NSString *aPath = [object gtm_pathForImageNamed:filename]; @@ -71,23 +72,25 @@ BOOL GTMIsObjectImageEqualToImageNamed(id object, filename = [filename stringByAppendingString:@"_Failed"]; } BOOL aSaved = [object gtm_saveToImageNamed:filename]; - NSString *fileNameWithExtension = [NSString stringWithFormat:@"%@.%@", - filename, [object gtm_imageExtension]]; + NSString *fileNameWithExtension + = [NSString stringWithFormat:@"%@.%@", + filename, [object gtm_imageExtension]]; NSString *fullSavePath = [object gtm_saveToPathForImageNamed:filename]; if (NO == aSaved) { if (!aPath) { - failString = [NSString stringWithFormat:@"File %@ did not exist in bundle. " - "Tried to save as %@ and failed.", + failString = [NSString stringWithFormat:@"File %@ did not exist in " + @"bundle. Tried to save as %@ and failed.", fileNameWithExtension, fullSavePath]; } else { - failString = [NSString stringWithFormat:@"Object image different than file %@. " - "Tried to save as %@ and failed.", + failString = [NSString stringWithFormat:@"Object image different " + @"than file %@. Tried to save as %@ and failed.", aPath, fullSavePath]; } } else { if (!aPath) { - failString = [NSString stringWithFormat:@"File %@ did not exist in bundle. " - "Saved to %@", fileNameWithExtension, fullSavePath]; + failString = [NSString stringWithFormat:@"File %@ did not exist in " + @" bundle. Saved to %@", fileNameWithExtension, + fullSavePath]; } else { NSString *diffPath = [filename stringByAppendingString:@"_Diff"]; diffPath = [object gtm_saveToPathForImageNamed:diffPath]; @@ -97,13 +100,14 @@ BOOL GTMIsObjectImageEqualToImageNamed(id object, } if ([data writeToFile:diffPath atomically:YES]) { failString = [NSString stringWithFormat:@"Object image different " - "than file %@. Saved image to %@. Saved diff to %@", + @"than file %@. Saved image to %@. " + @"Saved diff to %@", aPath, fullSavePath, diffPath]; } else { failString = [NSString stringWithFormat:@"Object image different " - "than file %@. Saved image to %@. Unable to save " - "diff. Most likely the image and diff are " - "different sizes.", + @"than file %@. Saved image to %@. Unable to save " + @"diff. Most likely the image and diff are " + @"different sizes.", aPath, fullSavePath]; } } @@ -146,21 +150,22 @@ BOOL GTMIsObjectStateEqualToStateNamed(id object, NSString *fullSavePath = [object gtm_saveToPathForStateNamed:filename]; if (NO == aSaved) { if (!aPath) { - failString = [NSString stringWithFormat:@"File %@ did not exist in bundle. " - "Tried to save as %@ and failed.", + failString = [NSString stringWithFormat:@"File %@ did not exist in " + @"bundle. Tried to save as %@ and failed.", fileNameWithExtension, fullSavePath]; } else { - failString = [NSString stringWithFormat:@"Object state different than file %@. " - "Tried to save as %@ and failed.", + failString = [NSString stringWithFormat:@"Object state different " + @"than file %@. Tried to save as %@ and failed.", aPath, fullSavePath]; } } else { if (!aPath) { - failString = [NSString stringWithFormat:@"File %@ did not exist in bundle. " - "Saved to %@", fileNameWithExtension, fullSavePath]; + failString = [NSString stringWithFormat:@"File %@ did not exist in " + @ "bundle. Saved to %@", fileNameWithExtension, + fullSavePath]; } else { - failString = [NSString stringWithFormat:@"Object state different than file %@. " - "Saved to %@", aPath, fullSavePath]; + failString = [NSString stringWithFormat:@"Object state different " + @"than file %@. Saved to %@", aPath, fullSavePath]; } } } @@ -173,6 +178,41 @@ BOOL GTMIsObjectStateEqualToStateNamed(id object, return isGood; } +CGContextRef GTMCreateUnitTestBitmapContextOfSizeWithData(CGSize size, + unsigned char **data) { + CGContextRef context = NULL; + size_t height = size.height; + size_t width = size.width; + size_t bytesPerRow = width * 4; + size_t bitsPerComponent = 8; + CGColorSpaceRef cs = NULL; +#if GTM_IPHONE_SDK + cs = CGColorSpaceCreateDeviceRGB(); +#else + cs = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); +#endif + _GTMDevAssert(cs, @"Couldn't create colorspace"); + CGBitmapInfo info + = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault; + if (data) { + *data = (unsigned char*)calloc(bytesPerRow, height); + _GTMDevAssert(*data, @"Couldn't create bitmap"); + } + context = CGBitmapContextCreate(data ? *data : NULL, width, height, + bitsPerComponent, bytesPerRow, cs, info); + _GTMDevAssert(context, @"Couldn't create an context"); + if (!data) { + CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height)); + } + CGContextSetRenderingIntent(context, kCGRenderingIntentRelativeColorimetric); + CGContextSetInterpolationQuality(context, kCGInterpolationNone); + CGContextSetShouldAntialias(context, NO); + CGContextSetAllowsAntialiasing(context, NO); + CGContextSetShouldSmoothFonts(context, NO); + CGColorSpaceRelease(cs); + return context; +} + @interface NSObject (GTMUnitTestingAdditionsPrivate) /// Find the path for a file named name.extension in your bundle. // Searches for the following: @@ -198,10 +238,11 @@ BOOL GTMIsObjectStateEqualToStateNamed(id object, // the path if the file exists in your bundle // or nil if no file is found // -- (NSString *)gtm_pathForFileNamed:(NSString*)name extension:(NSString*)extension; +- (NSString *)gtm_pathForFileNamed:(NSString*)name + extension:(NSString*)extension; - (NSString *)gtm_saveToPathForFileNamed:(NSString*)name extension:(NSString*)extension; -- (CGImageRef)gtm_createUnitTestImage; +- (CGImageRef)gtm_unitTestImage; // Returns nil if there is no override - (NSString *)gtm_getOverrideDefaultUnitTestSaveToDirectory; @end @@ -259,7 +300,8 @@ GTM_INLINE BOOL almostEqual(unsigned char a, unsigned char b) { // Arguments: // key - key to check for in dictionary - (void)checkForKey:(NSString*)key { - _GTMDevAssert(![dictionary_ objectForKey:key], @"Key already exists for %@", key); + _GTMDevAssert(![dictionary_ objectForKey:key], + @"Key already exists for %@", key); } // Key routine for the encoder. We store objects in our dictionary based on @@ -289,11 +331,12 @@ GTM_INLINE BOOL almostEqual(unsigned char a, unsigned char b) { // We then send out a notification to let other folks // add data for this object - NSDictionary *notificationDict = [NSDictionary dictionaryWithObject:self - forKey:GTMUnitTestingEncoderKey]; - [[NSNotificationCenter defaultCenter] postNotificationName:GTMUnitTestingEncodedObjectNotification - object:objv - userInfo:notificationDict]; + NSDictionary *notificationDict + = [NSDictionary dictionaryWithObject:self forKey:GTMUnitTestingEncoderKey]; + NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; + [nc postNotificationName:GTMUnitTestingEncodedObjectNotification + object:objv + userInfo:notificationDict]; // If we got anything from the object, or from the notification, store it in // our dictionary. Otherwise store the description. @@ -385,15 +428,17 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; if (!gGTMUnitTestSaveToDirectory) { #if GTM_IPHONE_SDK // Developer build, use their home directory Desktop. - gGTMUnitTestSaveToDirectory = [[[[[NSHomeDirectory() stringByDeletingLastPathComponent] - stringByDeletingLastPathComponent] - stringByDeletingLastPathComponent] - stringByDeletingLastPathComponent] - stringByAppendingPathComponent:@"Desktop"]; + gGTMUnitTestSaveToDirectory + = [[[[[NSHomeDirectory() stringByDeletingLastPathComponent] + stringByDeletingLastPathComponent] + stringByDeletingLastPathComponent] + stringByDeletingLastPathComponent] + stringByAppendingPathComponent:@"Desktop"]; #else - NSArray *desktopDirs = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, - NSUserDomainMask, - YES); + NSArray *desktopDirs + = NSSearchPathForDirectoriesInDomains(NSDesktopDirectory, + NSUserDomainMask, + YES); gGTMUnitTestSaveToDirectory = [desktopDirs objectAtIndex:0]; #endif // Did we get overridden? @@ -462,8 +507,9 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; NSString *thePath = nil; Class bundleClass = [GTMUnitTestingAdditionsBundleFinder class]; NSBundle *myBundle = [NSBundle bundleForClass:bundleClass]; - _GTMDevAssert(myBundle, @"Couldn't find bundle for class: %@ searching for file:%@.%@", - NSStringFromClass(bundleClass), name, extension); + _GTMDevAssert(myBundle, + @"Couldn't find bundle for class: %@ searching for file:%@.%@", + NSStringFromClass(bundleClass), name, extension); // System Version SInt32 major, minor, bugFix; [GTMSystemVersion getMajor:&major minor:&minor bugFix:&bugFix]; @@ -475,7 +521,8 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; systemVersions[3] = @""; NSString *extensions[2]; extensions[0] - = [NSString stringWithFormat:@".%@", [GTMSystemVersion runtimeArchitecture]]; + = [NSString stringWithFormat:@".%@", + [GTMSystemVersion runtimeArchitecture]]; extensions[1] = @""; size_t i, j; @@ -516,54 +563,6 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; #pragma mark UnitTestImage -// Create a CGColorSpaceRef appropriate for using in creating a unit test image -// iPhone uses device colorspace. -// Returns: -// an CGColorSpaceRef of the object. Caller must release -- (CGColorSpaceRef)gtm_createUnitTestColorspace { -#if GTM_IPHONE_SDK - return CGColorSpaceCreateDeviceRGB(); -#else - return CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); -#endif -} - -// Create a CGBitmapContextRef appropriate for using in creating a unit test -// image. If data is non-NULL, returns the buffer that the bitmap is -// using for it's underlying storage. You must free this buffer using -// free. If data is NULL, uses it's own internal storage. -// -// Returns: -// an CGContextRef of the object. Caller must release -- (CGContextRef)gtm_createUnitTestBitmapContextOfSize:(CGSize)size - data:(unsigned char**)data { - CGContextRef context = NULL; - size_t height = size.height; - size_t width = size.width; - size_t bytesPerRow = width * 4; - size_t bitsPerComponent = 8; - CGColorSpaceRef cs = [self gtm_createUnitTestColorspace]; - _GTMDevAssert(cs, @"Couldn't create colorspace"); - CGBitmapInfo info = kCGImageAlphaPremultipliedLast | kCGBitmapByteOrderDefault; - if (data) { - *data = (unsigned char*)calloc(bytesPerRow, height); - _GTMDevAssert(*data, @"Couldn't create bitmap"); - } - context = CGBitmapContextCreate(data ? *data : NULL, width, height, - bitsPerComponent, bytesPerRow, cs, info); - _GTMDevAssert(context, @"Couldn't create an context"); - if (!data) { - CGContextClearRect(context, CGRectMake(0, 0, size.width, size.height)); - } - CGContextSetRenderingIntent(context, kCGRenderingIntentRelativeColorimetric); - CGContextSetInterpolationQuality(context, kCGInterpolationNone); - CGContextSetShouldAntialias(context, NO); - CGContextSetAllowsAntialiasing(context, NO); - CGContextSetShouldSmoothFonts(context, NO); - CFRelease(cs); - return context; -} - // Checks to see that system settings are valid for doing an image comparison. // To be overridden by subclasses. // Returns: @@ -598,8 +597,8 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; } return nil; #else - CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, - kUTTagClassFilenameExtension); + CFStringRef extension + = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension); _GTMDevAssert(extension, @"No extension for uti: %@", uti); return GTMCFAutorelease(extension); @@ -626,19 +625,24 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; } #else data = [NSMutableData data]; - CGImageDestinationRef dest = CGImageDestinationCreateWithData((CFMutableDataRef)data, - [self gtm_imageUTI], - 1, - NULL); + CGImageDestinationRef dest + = CGImageDestinationCreateWithData((CFMutableDataRef)data, + [self gtm_imageUTI], + 1, + NULL); // LZW Compression for TIFF - NSDictionary *tiffDict = [NSDictionary dictionaryWithObject:[NSNumber numberWithInt:NSTIFFCompressionLZW] - forKey:(const NSString*)kCGImagePropertyTIFFCompression]; - NSDictionary *destProps = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithFloat:1.0f], - (const NSString*)kCGImageDestinationLossyCompressionQuality, - tiffDict, - (const NSString*)kCGImagePropertyTIFFDictionary, - nil]; + NSDictionary *tiffDict + = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInt:NSTIFFCompressionLZW], + (const NSString*)kCGImagePropertyTIFFCompression, + nil]; + NSDictionary *destProps + = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithFloat:1.0f], + (const NSString*)kCGImageDestinationLossyCompressionQuality, + tiffDict, + (const NSString*)kCGImagePropertyTIFFDictionary, + nil]; CGImageDestinationAddImage(dest, image, (CFDictionaryRef)destProps); CGImageDestinationFinalize(dest); CFRelease(dest); @@ -684,7 +688,7 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; // // Returns: // A CGImageRef that you own, or nil if no image at path -- (CGImageRef)gtm_createImageUsingPath:(NSString*)path { +- (CGImageRef)gtm_imageWithContentsOfFile:(NSString*)path { CGImageRef imageRef = nil; #if GTM_IPHONE_SDK UIImage *image = [UIImage imageWithContentsOfFile:path]; @@ -703,7 +707,7 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; } } #endif - return imageRef; + return (CGImageRef)GTMCFAutorelease(imageRef); } /// Compares unitTestImage of |self| to the image located at |path| @@ -721,10 +725,10 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; if (diff) { *diff = nil; } - CGImageRef fileRep = [self gtm_createImageUsingPath:path]; + CGImageRef fileRep = [self gtm_imageWithContentsOfFile:path]; _GTMDevAssert(fileRep, @"Unable to create imagerep from %@", path); - CGImageRef imageRep = [self gtm_createUnitTestImage]; + CGImageRef imageRep = [self gtm_unitTestImage]; _GTMDevAssert(imageRep, @"Unable to create imagerep for %@", self); size_t fileHeight = CGImageGetHeight(fileRep); @@ -743,12 +747,12 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; CGRect imageRect = CGRectMake(0, 0, fileWidth, fileHeight); unsigned char *fileData; unsigned char *imageData; - CGContextRef fileContext = [self gtm_createUnitTestBitmapContextOfSize:imageSize - data:&fileData]; + CGContextRef fileContext + = GTMCreateUnitTestBitmapContextOfSizeWithData(imageSize, &fileData); _GTMDevAssert(fileContext, @"Unable to create filecontext"); CGContextDrawImage(fileContext, imageRect, fileRep); - CGContextRef imageContext =[self gtm_createUnitTestBitmapContextOfSize:imageSize - data:&imageData]; + CGContextRef imageContext + = GTMCreateUnitTestBitmapContextOfSizeWithData(imageSize, &imageData); _GTMDevAssert(imageContext, @"Unable to create imageContext"); CGContextDrawImage(imageContext, imageRect, imageRep); @@ -767,8 +771,8 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; if (!answer && diff) { answer = YES; unsigned char *diffData; - CGContextRef diffContext = [self gtm_createUnitTestBitmapContextOfSize:imageSize - data:&diffData]; + CGContextRef diffContext + = GTMCreateUnitTestBitmapContextOfSizeWithData(imageSize, &diffData); _GTMDevAssert(diffContext, @"Can't make diff context"); size_t diffRowBytes = CGBitmapContextGetBytesPerRow(diffContext); for (row = 0; row < imageHeight; row++) { @@ -821,8 +825,6 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; free(imageData); CFRelease(imageContext); } - CGImageRelease(imageRep); - CGImageRelease(fileRep); return answer; } @@ -853,10 +855,10 @@ static NSString *gGTMUnitTestSaveToDirectory = nil; // nil if failed // - (NSData *)gtm_imageRepresentation { - CGImageRef imageRep = [self gtm_createUnitTestImage]; + CGImageRef imageRep = [self gtm_unitTestImage]; NSData *data = [self gtm_imageDataForImage:imageRep]; - _GTMDevAssert(data, @"unable to create %@ from %@", [self gtm_imageExtension], self); - CFRelease(imageRep); + _GTMDevAssert(data, @"unable to create %@ from %@", + [self gtm_imageExtension], self); return data; } diff --git a/UnitTesting/GTMUIKit+UnitTesting.h b/UnitTesting/GTMUIKit+UnitTesting.h index bb78a7a..ee420e9 100644 --- a/UnitTesting/GTMUIKit+UnitTesting.h +++ b/UnitTesting/GTMUIKit+UnitTesting.h @@ -65,12 +65,6 @@ // See GTMNSObject+UnitTesting.h for details. @interface UIView (GTMUnitTestingAdditions) <GTMUnitTestingImaging> -// Returns an image containing a representation suitable for use in comparing against a master image. -// -// Returns: -// an image of the object -- (CGImageRef)gtm_createUnitTestImage; - // Encodes the state of an object in a manner suitable for comparing against a master state file // This enables us to determine whether the object is in a suitable state. // @@ -89,12 +83,6 @@ // GTMAssertObjectImageEqualToImageNamed macro, which automatically creates // result images and diff images in case test fails. @interface UIImage (GTMUnitTestingAdditions) <GTMUnitTestingImaging> -// Returns an image containing a representation suitable for use in comparing -// against a master image. -// -// Returns: -// an image of the object -- (CGImageRef)gtm_createUnitTestImage; @end // A view that allows you to delegate out drawing using the formal diff --git a/UnitTesting/GTMUIKit+UnitTesting.m b/UnitTesting/GTMUIKit+UnitTesting.m index 56460be..7d3f200 100644 --- a/UnitTesting/GTMUIKit+UnitTesting.m +++ b/UnitTesting/GTMUIKit+UnitTesting.m @@ -74,9 +74,9 @@ // // Returns: // an image of the object -- (CGImageRef)gtm_createUnitTestImage { +- (CGImageRef)gtm_unitTestImage { CALayer* layer = [self layer]; - return [layer gtm_createUnitTestImage]; + return [layer gtm_unitTestImage]; } // Encodes the state of an object in a manner suitable for comparing @@ -116,9 +116,7 @@ @end @implementation UIImage (GTMUnitTestingAdditions) -- (CGImageRef)gtm_createUnitTestImage { - CGImageRef imageRef = [self CGImage]; - CGImageRetain(imageRef); - return imageRef; +- (CGImageRef)gtm_unitTestImage { + return [self CGImage]; } @end diff --git a/UnitTesting/GTMUnitTestingTest.m b/UnitTesting/GTMUnitTestingTest.m index 5d2a9f3..72e6880 100644 --- a/UnitTesting/GTMUnitTestingTest.m +++ b/UnitTesting/GTMUnitTestingTest.m @@ -79,7 +79,7 @@ NSString *const kGTMWindowSaveFileName = @"GTMUnitTestingWindow"; // Clean up [NSApp setDelegate:nil]; [appDelegate release]; - [window close]; + [testWindowController release]; } - (void)testViewUnitTesting { |