// // GTMFoundationUnitTestingUtilities.m // // Copyright 2006-2010 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 #import "GTMDefines.h" #import "GTMFoundationUnitTestingUtilities.h" @implementation GTMFoundationUnitTestingUtilities // Returns YES if we are currently being unittested. + (BOOL)areWeBeingUnitTested { BOOL answer = NO; Class testProbeClass; #if GTM_USING_XCTEST testProbeClass = NSClassFromString(@"XCTestProbe"); #else testProbeClass = NSClassFromString(@"SenTestProbe"); #endif if (testProbeClass != Nil) { // Doing this little dance so we don't actually have to link // SenTestingKit in SEL selector = NSSelectorFromString(@"isTesting"); NSMethodSignature *sig = [testProbeClass methodSignatureForSelector:selector]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:sig]; [invocation setSelector:selector]; [invocation invokeWithTarget:testProbeClass]; [invocation getReturnValue:&answer]; } return answer; } + (void)maxRuntimeTimer:(NSTimer*)timer { // Directly use fprintf so the message always shows up. fprintf(stderr, "%s:%d: error: %s : Hit app testing timeout!\n", __FILE__, __LINE__, __func__); fflush(stderr); exit(1); } + (void)installTestingTimeout:(NSTimeInterval)maxRunInterval { [NSTimer scheduledTimerWithTimeInterval:maxRunInterval target:self selector:@selector(maxRuntimeTimer:) userInfo:nil repeats:NO]; } @end @implementation GTMUnitTestingBooleanRunLoopContext + (id)context { return [[[GTMUnitTestingBooleanRunLoopContext alloc] init] autorelease]; } - (BOOL)shouldStop { return shouldStop_; } - (void)setShouldStop:(BOOL)stop { shouldStop_ = stop; } - (void)reset { shouldStop_ = NO; } @end @implementation NSRunLoop (GTMUnitTestingAdditions) - (BOOL)gtm_runUpToNSeconds:(NSTimeInterval)seconds context:(id)context { return [self gtm_runUntilDate:[NSDate dateWithTimeIntervalSinceNow:seconds] context:context]; } - (BOOL)gtm_runUpToSixtySecondsWithContext:(id)context { return [self gtm_runUntilDate:[NSDate dateWithTimeIntervalSinceNow:60] context:context]; } - (BOOL)gtm_runUntilDate:(NSDate *)date context:(id)context { return [self gtm_runUntilDate:date mode:NSDefaultRunLoopMode context:context]; } - (BOOL)gtm_runUntilDate:(NSDate *)date mode:(NSString *)mode context:(id)context { BOOL contextShouldStop = NO; NSDate* next = nil; while (1) { contextShouldStop = [context shouldStop]; if (contextShouldStop) break; next = [[NSDate alloc] initWithTimeIntervalSinceNow:0.01]; if (!([self runMode:mode beforeDate:next])) break; if ([next compare:date] == NSOrderedDescending) break; [next release]; next = nil; } [next release]; return contextShouldStop; } @end