diff options
Diffstat (limited to 'UnitTesting/GTMUnitTestDevLog.m')
-rw-r--r-- | UnitTesting/GTMUnitTestDevLog.m | 253 |
1 files changed, 30 insertions, 223 deletions
diff --git a/UnitTesting/GTMUnitTestDevLog.m b/UnitTesting/GTMUnitTestDevLog.m index 7a12bb0..ae4050f 100644 --- a/UnitTesting/GTMUnitTestDevLog.m +++ b/UnitTesting/GTMUnitTestDevLog.m @@ -18,52 +18,12 @@ #import "GTMUnitTestDevLog.h" - -#import "GTMRegex.h" -#import "GTMSenTestCase.h" - -#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) -// Some versions of GCC (4.2 and below AFAIK) aren't great about supporting -// -Wmissing-format-attribute -// when the function is anything more complex than foo(NSString *fmt, ...). -// You see the error inside the function when you turn ... into va_args and -// attempt to call another function (like vsprintf for example). -// So we just shut off the warning for this file. We reenable it at the end. -#pragma GCC diagnostic ignored "-Wmissing-format-attribute" -#endif // !__clang__ - -#if !GTM_IPHONE_SDK -// Add support for grabbing messages from Carbon. -#import <CoreServices/CoreServices.h> -static void GTMDevLogDebugAssert(OSType componentSignature, - UInt32 options, - const char *assertionString, - const char *exceptionLabelString, - const char *errorString, - const char *fileName, - long lineNumber, - void *value, - ConstStr255Param outputMsg) { - NSString *outLog = [[[NSString alloc] initWithBytes:&(outputMsg[1]) - length:StrLength(outputMsg) - encoding:NSMacOSRomanStringEncoding] - autorelease]; - _GTMDevLog(@"%@", outLog); // Don't want any percents in outLog honored -} -static inline void GTMInstallDebugAssertOutputHandler(void) { - InstallDebugAssertOutputHandler(GTMDevLogDebugAssert); -} -static inline void GTMUninstallDebugAssertOutputHandler(void) { - InstallDebugAssertOutputHandler(NULL); -} -#else // GTM_IPHONE_SDK -static inline void GTMInstallDebugAssertOutputHandler(void) {}; -static inline void GTMUninstallDebugAssertOutputHandler(void) {}; -#endif // GTM_IPHONE_SDK - -NSString *const GTMLogFailureException = @"GTMLogFailureException"; - @interface GTMUnttestDevLogAssertionHandler : NSAssertionHandler +- (void)handleFailure:(NSString *)functionName + file:(NSString *)fileName + lineNumber:(NSInteger)line + description:(NSString *)format + arguments:(va_list)argList NS_FORMAT_FUNCTION(4,0); @end @implementation GTMUnttestDevLogAssertionHandler @@ -72,24 +32,18 @@ NSString *const GTMLogFailureException = @"GTMLogFailureException"; file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format, ... { + NSString *call = [NSString stringWithFormat:@"[%@ %@]", + NSStringFromClass([object class]), + NSStringFromSelector(selector)]; + va_list argList; va_start(argList, format); - NSString *descStr - = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease]; + [self handleFailure:call + file:fileName + lineNumber:line + description:format + arguments:argList]; va_end(argList); - - // You need a format that will be useful in logs, but won't trip up Xcode or - // any other build systems parsing of the output. - NSString *outLog - = [NSString stringWithFormat:@"RecordedNSAssert in %@ - %@ (%@:%ld)", - NSStringFromSelector(selector), - descStr, - fileName, (long)line]; - // To avoid unused variable warning when _GTMDevLog is stripped. - (void)outLog; - _GTMDevLog(@"%@", outLog); // Don't want any percents in outLog honored - [NSException raise:NSInternalInconsistencyException - format:@"NSAssert raised"]; } - (void)handleFailureInFunction:(NSString *)functionName @@ -98,45 +52,38 @@ NSString *const GTMLogFailureException = @"GTMLogFailureException"; description:(NSString *)format, ... { va_list argList; va_start(argList, format); - NSString *descStr - = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease]; + [self handleFailure:functionName + file:fileName + lineNumber:line + description:format + arguments:argList]; va_end(argList); +} + +- (void)handleFailure:(NSString *)failure + file:(NSString *)fileName + lineNumber:(NSInteger)line + description:(NSString *)format + arguments:(va_list)argList { + NSString *descStr + = [[[NSString alloc] initWithFormat:format arguments:argList] autorelease]; // You need a format that will be useful in logs, but won't trip up Xcode or // any other build systems parsing of the output. NSString *outLog - = [NSString stringWithFormat:@"RecordedNSAssert in %@ - %@ (%@:%ld)", - functionName, - descStr, - fileName, (long)line]; + = [NSString stringWithFormat:@"RecordedNSAssert in %@ - %@ (%@:%ld)", + failure, descStr, fileName, (long)line]; // To avoid unused variable warning when _GTMDevLog is stripped. (void)outLog; _GTMDevLog(@"%@", outLog); // Don't want any percents in outLog honored [NSException raise:NSInternalInconsistencyException format:@"NSAssert raised"]; } - @end @implementation GTMUnitTestDevLog -// If unittests are ever being run on separate threads, this may need to be -// made a thread local variable. -static BOOL gTrackingEnabled = NO; - -+ (NSMutableArray *)patterns { - static NSMutableArray *patterns = nil; - if (!patterns) { - patterns = [[NSMutableArray array] retain]; - } - return patterns; -} - -+ (BOOL)isTrackingEnabled { - return gTrackingEnabled; -} + (void)enableTracking { - GTMInstallDebugAssertOutputHandler(); NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; @@ -148,154 +95,14 @@ static BOOL gTrackingEnabled = NO; GTMUnttestDevLogAssertionHandler *handler = [[[GTMUnttestDevLogAssertionHandler alloc] init] autorelease]; [threadDictionary setObject:handler forKey:@"NSAssertionHandler"]; - - gTrackingEnabled = YES; } + (void)disableTracking { - GTMUninstallDebugAssertOutputHandler(); // Clear our assertion handler back out. NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary]; [threadDictionary removeObjectForKey:@"NSAssertionHandler"]; - - gTrackingEnabled = NO; } -+ (void)log:(NSString*)format, ... { - va_list argList; - va_start(argList, format); - [self log:format args:argList]; - va_end(argList); -} - -+ (void)log:(NSString*)format args:(va_list)args { - if ([self isTrackingEnabled]) { - NSString *logString = [[[NSString alloc] initWithFormat:format - arguments:args] autorelease]; - @synchronized(self) { - NSMutableArray *patterns = [self patterns]; - BOOL logError = [patterns count] == 0 ? YES : NO; - GTMRegex *regex = nil; - if (!logError) { - regex = [[[patterns objectAtIndex:0] retain] autorelease]; - logError = [regex matchesString:logString] ? NO : YES; - [patterns removeObjectAtIndex:0]; - } - if (logError) { - - if (regex) { - [NSException raise:GTMLogFailureException - format:@"Unexpected log: %@\nExpected: %@", - logString, regex]; - } else { - [NSException raise:GTMLogFailureException - format:@"Unexpected log: %@", logString]; - } - } else { - static BOOL envChecked = NO; - static BOOL showExpectedLogs = YES; - if (!envChecked) { - showExpectedLogs = getenv("GTM_SHOW_UNITTEST_DEVLOGS") ? YES : NO; - } - if (showExpectedLogs) { - NSLog(@"Expected Log: %@", logString); - } - } - } - } else { - NSLogv(format, args); - } -} - -+ (void)expectString:(NSString *)format, ... { - va_list argList; - va_start(argList, format); - NSString *string = [[[NSString alloc] initWithFormat:format - arguments:argList] autorelease]; - va_end(argList); - NSString *pattern = [GTMRegex escapedPatternForString:string]; - [self expect:1 casesOfPattern:@"%@", pattern]; - -} - -+ (void)expectPattern:(NSString *)format, ... { - va_list argList; - va_start(argList, format); - [self expect:1 casesOfPattern:format args:argList]; - va_end(argList); -} - -+ (void)expect:(NSUInteger)n casesOfString:(NSString *)format, ... { - va_list argList; - va_start(argList, format); - NSString *string = [[[NSString alloc] initWithFormat:format - arguments:argList] autorelease]; - va_end(argList); - NSString *pattern = [GTMRegex escapedPatternForString:string]; - [self expect:n casesOfPattern:@"%@", pattern]; -} - -+ (void)expect:(NSUInteger)n casesOfPattern:(NSString*)format, ... { - va_list argList; - va_start(argList, format); - [self expect:n casesOfPattern:format args:argList]; - va_end(argList); -} - -+ (void)expect:(NSUInteger)n -casesOfPattern:(NSString*)format - args:(va_list)args { - NSString *pattern = [[[NSString alloc] initWithFormat:format - arguments:args] autorelease]; - GTMRegex *regex = [GTMRegex regexWithPattern:pattern - options:kGTMRegexOptionSupressNewlineSupport]; - @synchronized(self) { - NSMutableArray *patterns = [self patterns]; - for (NSUInteger i = 0; i < n; ++i) { - [patterns addObject:regex]; - } - } -} - -+ (void)verifyNoMoreLogsExpected { - @synchronized(self) { - NSMutableArray *patterns = [self patterns]; - if ([patterns count] > 0) { - NSMutableArray *patternsCopy = [[patterns copy] autorelease]; - [self resetExpectedLogs]; - [NSException raise:GTMLogFailureException - format:@"Logs still expected %@", patternsCopy]; - } - } -} - -+ (void)resetExpectedLogs { - @synchronized(self) { - NSMutableArray *patterns = [self patterns]; - [patterns removeAllObjects]; - } -} @end - - -@implementation GTMUnitTestDevLogDebug - -+ (void)expect:(NSUInteger)n -casesOfPattern:(NSString*)format - args:(va_list)args { -#if DEBUG - // In debug, let the base work happen - [super expect:n casesOfPattern:format args:args]; -#else - // nothing when not in debug -#endif -} - -@end - -#if !defined(__clang__) && (__GNUC__*10+__GNUC_MINOR__ >= 42) -// See comment at top of file. -#pragma GCC diagnostic error "-Wmissing-format-attribute" -#endif // !__clang__ |