/MapView/GTM/GTMIPhoneUnitTestDelegate.m
Objective C | 165 lines | 128 code | 10 blank | 27 comment | 10 complexity | 43f137ba6c30598bb31effd48acf54e8 MD5 | raw file
1// 2// GTMIPhoneUnitTestDelegate.m 3// 4// Copyright 2008 Google Inc. 5// 6// Licensed under the Apache License, Version 2.0 (the "License"); you may not 7// use this file except in compliance with the License. You may obtain a copy 8// of the License at 9// 10// http://www.apache.org/licenses/LICENSE-2.0 11// 12// Unless required by applicable law or agreed to in writing, software 13// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15// License for the specific language governing permissions and limitations under 16// the License. 17// 18 19#import "GTMIPhoneUnitTestDelegate.h" 20 21#import "GTMDefines.h" 22#if !GTM_IPHONE_SDK 23#error GTMIPhoneUnitTestDelegate for iPhone only 24#endif 25#import <objc/runtime.h> 26#import <stdio.h> 27#import <UIKit/UIKit.h> 28#import "GTMSenTestCase.h" 29 30@implementation GTMIPhoneUnitTestDelegate 31 32// Run through all the registered classes and run test methods on any 33// that are subclasses of SenTestCase. Terminate the application upon 34// test completion. 35- (void)applicationDidFinishLaunching:(UIApplication *)application { 36 [self runTests]; 37 38 if (!getenv("GTM_DISABLE_TERMINATION")) { 39 // To help using xcodebuild, make the exit status 0/1 to signal the tests 40 // success/failure. 41 int exitStatus = (([self totalFailures] == 0U) ? 0 : 1); 42 // Alternative to exit(status); so it cleanly terminates the UIApplication 43 // and classes that depend on this signal to exit cleanly. 44 if ([application respondsToSelector:@selector(_terminateWithStatus:)]) { 45 [application performSelector:@selector(_terminateWithStatus:) 46 withObject:(id)exitStatus]; 47 } else { 48 exit(exitStatus); 49 } 50 } 51} 52 53// Run through all the registered classes and run test methods on any 54// that are subclasses of SenTestCase. Print results and run time to 55// the default output. 56- (void)runTests { 57 int count = objc_getClassList(NULL, 0); 58 NSMutableData *classData 59 = [NSMutableData dataWithLength:sizeof(Class) * count]; 60 Class *classes = (Class*)[classData mutableBytes]; 61 _GTMDevAssert(classes, @"Couldn't allocate class list"); 62 objc_getClassList(classes, count); 63 totalFailures_ = 0; 64 totalSuccesses_ = 0; 65 NSString *suiteName = [[NSBundle mainBundle] bundlePath]; 66 NSDate *suiteStartDate = [NSDate date]; 67 NSString *suiteStartString 68 = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", 69 suiteName, suiteStartDate]; 70 fputs([suiteStartString UTF8String], stderr); 71 fflush(stderr); 72 for (int i = 0; i < count; ++i) { 73 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 74 Class currClass = classes[i]; 75 if (class_respondsToSelector(currClass, @selector(conformsToProtocol:)) && 76 [currClass conformsToProtocol:@protocol(SenTestCase)]) { 77 NSDate *fixtureStartDate = [NSDate date]; 78 NSString *fixtureName = NSStringFromClass(currClass); 79 NSString *fixtureStartString 80 = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n", 81 fixtureName, fixtureStartDate]; 82 int fixtureSuccesses = 0; 83 int fixtureFailures = 0; 84 fputs([fixtureStartString UTF8String], stderr); 85 fflush(stderr); 86 NSArray *invocations = [currClass testInvocations]; 87 if ([invocations count]) { 88 NSInvocation *invocation; 89 GTM_FOREACH_OBJECT(invocation, invocations) { 90 GTMTestCase *testCase 91 = [[currClass alloc] initWithInvocation:invocation]; 92 BOOL failed = NO; 93 NSDate *caseStartDate = [NSDate date]; 94 NSString *selectorName = NSStringFromSelector([invocation selector]); 95 NSString *caseStartString 96 = [NSString stringWithFormat:@"Test Case '-[%@ %@]' started.\n", 97 fixtureName, selectorName]; 98 fputs([caseStartString UTF8String], stderr); 99 fflush(stderr); 100 @try { 101 [testCase performTest]; 102 } @catch (NSException *exception) { 103 failed = YES; 104 } 105 if (failed) { 106 fixtureFailures += 1; 107 } else { 108 fixtureSuccesses += 1; 109 } 110 NSTimeInterval caseEndTime 111 = [[NSDate date] timeIntervalSinceDate:caseStartDate]; 112 NSString *caseEndString 113 = [NSString stringWithFormat:@"Test Case '-[%@ %@]' %@ (%0.3f " 114 @"seconds).\n", 115 fixtureName, selectorName, 116 failed ? @"failed" : @"passed", 117 caseEndTime]; 118 fputs([caseEndString UTF8String], stderr); 119 fflush(stderr); 120 [testCase release]; 121 } 122 } 123 NSDate *fixtureEndDate = [NSDate date]; 124 NSTimeInterval fixtureEndTime 125 = [fixtureEndDate timeIntervalSinceDate:fixtureStartDate]; 126 NSString *fixtureEndString 127 = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" 128 @"Executed %d tests, with %d failures (%d " 129 @"unexpected) in %0.3f (%0.3f) seconds\n\n", 130 fixtureName, fixtureEndDate, 131 fixtureSuccesses + fixtureFailures, 132 fixtureFailures, fixtureFailures, 133 fixtureEndTime, fixtureEndTime]; 134 135 fputs([fixtureEndString UTF8String], stderr); 136 fflush(stderr); 137 totalSuccesses_ += fixtureSuccesses; 138 totalFailures_ += fixtureFailures; 139 } 140 [pool release]; 141 } 142 NSDate *suiteEndDate = [NSDate date]; 143 NSTimeInterval suiteEndTime 144 = [suiteEndDate timeIntervalSinceDate:suiteStartDate]; 145 NSString *suiteEndString 146 = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n" 147 @"Executed %d tests, with %d failures (%d " 148 @"unexpected) in %0.3f (%0.3f) seconds\n\n", 149 suiteName, suiteEndDate, 150 totalSuccesses_ + totalFailures_, 151 totalFailures_, totalFailures_, 152 suiteEndTime, suiteEndTime]; 153 fputs([suiteEndString UTF8String], stderr); 154 fflush(stderr); 155} 156 157- (NSUInteger)totalSuccesses { 158 return totalSuccesses_; 159} 160 161- (NSUInteger)totalFailures { 162 return totalFailures_; 163} 164 165@end