Authored by Hal Mueller

adding unit testing

//
// GTMDefines.h
//
// 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.
//
// ============================================================================
// ----------------------------------------------------------------------------
// CPP symbols that can be overridden in a prefix to control how the toolbox
// is compiled.
// ----------------------------------------------------------------------------
// GTMHTTPFetcher will support logging by default but only hook its input
// stream support for logging when requested. You can control the inclusion of
// the code by providing your own definitions for these w/in a prefix header.
//
#ifndef GTM_HTTPFETCHER_ENABLE_LOGGING
# define GTM_HTTPFETCHER_ENABLE_LOGGING 1
#endif // GTM_HTTPFETCHER_ENABLE_LOGGING
#ifndef GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING
# define GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING 0
#endif // GTM_HTTPFETCHER_ENABLE_INPUTSTREAM_LOGGING
// _GTMDevLog & _GTMDevAssert
//
// _GTMDevLog & _GTMDevAssert are meant to be a very lightweight shell for
// developer level errors. This implementation simply macros to NSLog/NSAssert.
// It is not intended to be a general logging/reporting system.
//
// Please see http://code.google.com/p/google-toolbox-for-mac/wiki/DevLogNAssert
// for a little more background on the usage of these macros.
//
// _GTMDevLog log some error/problem in debug builds
// _GTMDevAssert assert if conditon isn't met w/in a method/function
// in all builds.
//
// To replace this system, just provide different macro definitions in your
// prefix header. Remember, any implementation you provide *must* be thread
// safe since this could be called by anything in what ever situtation it has
// been placed in.
//
// We only define the simple macros if nothing else has defined this.
#ifndef _GTMDevLog
#ifdef DEBUG
#define _GTMDevLog(...) NSLog(__VA_ARGS__)
#else
#define _GTMDevLog(...) do { } while (0)
#endif
#endif // _GTMDevLog
// Declared here so that it can easily be used for logging tracking if
// necessary. See GTMUnitTestDevLog.h for details.
@class NSString;
extern void _GTMUnittestDevLog(NSString *format, ...);
#ifndef _GTMDevAssert
// we directly invoke the NSAssert handler so we can pass on the varargs
// (NSAssert doesn't have a macro we can use that takes varargs)
#if !defined(NS_BLOCK_ASSERTIONS)
#define _GTMDevAssert(condition, ...) \
do { \
if (!(condition)) { \
[[NSAssertionHandler currentHandler] \
handleFailureInFunction:[NSString stringWithCString:__PRETTY_FUNCTION__] \
file:[NSString stringWithCString:__FILE__] \
lineNumber:__LINE__ \
description:__VA_ARGS__]; \
} \
} while(0)
#else // !defined(NS_BLOCK_ASSERTIONS)
#define _GTMDevAssert(condition, ...) do { } while (0)
#endif // !defined(NS_BLOCK_ASSERTIONS)
#endif // _GTMDevAssert
// _GTMCompileAssert
// _GTMCompileAssert is an assert that is meant to fire at compile time if you
// want to check things at compile instead of runtime. For example if you
// want to check that a wchar is 4 bytes instead of 2 you would use
// _GTMCompileAssert(sizeof(wchar_t) == 4, wchar_t_is_4_bytes_on_OS_X)
// Note that the second "arg" is not in quotes, and must be a valid processor
// symbol in it's own right (no spaces, punctuation etc).
// Wrapping this in an #ifndef allows external groups to define their own
// compile time assert scheme.
#ifndef _GTMCompileAssert
// We got this technique from here:
// http://unixjunkie.blogspot.com/2007/10/better-compile-time-asserts_29.html
#define _GTMCompileAssertSymbolInner(line, msg) _GTMCOMPILEASSERT ## line ## __ ## msg
#define _GTMCompileAssertSymbol(line, msg) _GTMCompileAssertSymbolInner(line, msg)
#define _GTMCompileAssert(test, msg) \
typedef char _GTMCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
#endif // _GTMCompileAssert
// ============================================================================
// ----------------------------------------------------------------------------
// CPP symbols defined based on the project settings so the GTM code has
// simple things to test against w/o scattering the knowledge of project
// setting through all the code.
// ----------------------------------------------------------------------------
// Provide a single constant CPP symbol that all of GTM uses for ifdefing
// iPhone code.
#include <TargetConditionals.h>
#if TARGET_OS_IPHONE // iPhone SDK
// For iPhone specific stuff
#define GTM_IPHONE_SDK 1
#else
// For MacOS specific stuff
#define GTM_MACOS_SDK 1
#endif
// To simplify support for 64bit (and Leopard in general), we provide the type
// defines for non Leopard SDKs
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
// NSInteger/NSUInteger and Max/Mins
#ifndef NSINTEGER_DEFINED
#if __LP64__ || NS_BUILD_32_LIKE_64
typedef long NSInteger;
typedef unsigned long NSUInteger;
#else
typedef int NSInteger;
typedef unsigned int NSUInteger;
#endif
#define NSIntegerMax LONG_MAX
#define NSIntegerMin LONG_MIN
#define NSUIntegerMax ULONG_MAX
#define NSINTEGER_DEFINED 1
#endif // NSINTEGER_DEFINED
// CGFloat
#ifndef CGFLOAT_DEFINED
#if defined(__LP64__) && __LP64__
// This really is an untested path (64bit on Tiger?)
typedef double CGFloat;
#define CGFLOAT_MIN DBL_MIN
#define CGFLOAT_MAX DBL_MAX
#define CGFLOAT_IS_DOUBLE 1
#else /* !defined(__LP64__) || !__LP64__ */
typedef float CGFloat;
#define CGFLOAT_MIN FLT_MIN
#define CGFLOAT_MAX FLT_MAX
#define CGFLOAT_IS_DOUBLE 0
#endif /* !defined(__LP64__) || !__LP64__ */
#define CGFLOAT_DEFINED 1
#endif // CGFLOAT_DEFINED
#endif // MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
... ...
//
// GTMIPhoneUnitTestDelegate.h
//
// 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.
//
// Application delegate that runs all test methods in registered classes
// extending SenTestCase. The application is terminated afterwards.
// You can also run the tests directly from your application by invoking
// gtm_runTests and clean up, restore data, etc. before the application
// terminates.
@interface GTMIPhoneUnitTestDelegate : NSObject
// Runs through all the registered classes and runs test methods on any
// that are subclasses of SenTestCase. Prints results and run time to
// the default output.
- (void)runTests;
@end
... ...
//
// GTMIPhoneUnitTestDelegate.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 "GTMIPhoneUnitTestDelegate.h"
#import "GTMDefines.h"
#if !GTM_IPHONE_SDK
#error GTMIPhoneUnitTestDelegate for iPhone only
#endif
#import <objc/runtime.h>
#import <stdio.h>
#import <UIKit/UIKit.h>
#import "GTMSenTestCase.h"
// Used for sorting methods below
static int MethodSort(const void *a, const void *b) {
const char *nameA = sel_getName(method_getName(*(Method*)a));
const char *nameB = sel_getName(method_getName(*(Method*)b));
return strcmp(nameA, nameB);
}
@interface UIApplication (iPhoneUnitTestAdditions)
// "Private" method that we need
- (void)terminate;
@end
@implementation GTMIPhoneUnitTestDelegate
// Return YES if class is subclass (1 or more generations) of SenTestCase
- (BOOL)isTestFixture:(Class)aClass {
BOOL iscase = NO;
Class testCaseClass = [SenTestCase class];
Class superclass;
for (superclass = aClass;
!iscase && superclass;
superclass = class_getSuperclass(superclass)) {
iscase = superclass == testCaseClass ? YES : NO;
}
return iscase;
}
// Run through all the registered classes and run test methods on any
// that are subclasses of SenTestCase. Terminate the application upon
// test completion.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[self runTests];
// Using private call to end our tests
[[UIApplication sharedApplication] terminate];
}
// Run through all the registered classes and run test methods on any
// that are subclasses of SenTestCase. Print results and run time to
// the default output.
- (void)runTests {
int count = objc_getClassList(NULL, 0);
Class *classes = (Class*)malloc(sizeof(Class) * count);
_GTMDevAssert(classes, @"Couldn't allocate class list");
objc_getClassList(classes, count);
int suiteSuccesses = 0;
int suiteFailures = 0;
int suiteTotal = 0;
NSString *suiteName = [[NSBundle mainBundle] bundlePath];
NSDate *suiteStartDate = [NSDate date];
NSString *suiteStartString = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n",
suiteName, suiteStartDate];
fputs([suiteStartString UTF8String], stderr);
fflush(stderr);
for (int i = 0; i < count; ++i) {
Class currClass = classes[i];
if ([self isTestFixture:currClass]) {
NSDate *fixtureStartDate = [NSDate date];
NSString *fixtureName = NSStringFromClass(currClass);
NSString *fixtureStartString = [NSString stringWithFormat:@"Test Suite '%@' started at %@\n",
fixtureName, fixtureStartDate];
int fixtureSuccesses = 0;
int fixtureFailures = 0;
int fixtureTotal = 0;
fputs([fixtureStartString UTF8String], stderr);
fflush(stderr);
id testcase = [[currClass alloc] init];
_GTMDevAssert(testcase, @"Unable to instantiate Test Suite: '%@'\n",
fixtureName);
unsigned int methodCount;
Method *methods = class_copyMethodList(currClass, &methodCount);
// Sort our methods so they are called in Alphabetical order just
// because we can.
qsort(methods, methodCount, sizeof(Method), MethodSort);
for (size_t j = 0; j < methodCount; ++j) {
Method currMethod = methods[j];
SEL sel = method_getName(currMethod);
const char *name = sel_getName(sel);
// If it starts with test, run it.
if (strstr(name, "test") == name) {
fixtureTotal += 1;
BOOL failed = NO;
NSDate *caseStartDate = [NSDate date];
@try {
[testcase performTest:sel];
} @catch (NSException *exception) {
failed = YES;
}
if (failed) {
fixtureFailures += 1;
} else {
fixtureSuccesses += 1;
}
NSTimeInterval caseEndTime = [[NSDate date] timeIntervalSinceDate:caseStartDate];
NSString *caseEndString = [NSString stringWithFormat:@"Test Case '-[%@ %s]' %s (%0.3f seconds).\n",
fixtureName, name,
failed ? "failed" : "passed", caseEndTime];
fputs([caseEndString UTF8String], stderr);
fflush(stderr);
}
}
if (methods) {
free(methods);
}
[testcase release];
NSDate *fixtureEndDate = [NSDate date];
NSTimeInterval fixtureEndTime = [fixtureEndDate timeIntervalSinceDate:fixtureStartDate];
NSString *fixtureEndString = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n"
"Executed %d tests, with %d failures (%d unexpected) in %0.3f (%0.3f) seconds\n",
fixtureName, fixtureEndDate, fixtureTotal,
fixtureFailures, fixtureFailures,
fixtureEndTime, fixtureEndTime];
fputs([fixtureEndString UTF8String], stderr);
fflush(stderr);
suiteTotal += fixtureTotal;
suiteSuccesses += fixtureSuccesses;
suiteFailures += fixtureFailures;
}
}
NSDate *suiteEndDate = [NSDate date];
NSTimeInterval suiteEndTime = [suiteEndDate timeIntervalSinceDate:suiteStartDate];
NSString *suiteEndString = [NSString stringWithFormat:@"Test Suite '%@' finished at %@.\n"
"Executed %d tests, with %d failures (%d unexpected) in %0.3f (%0.3f) seconds\n",
suiteName, suiteEndDate, suiteTotal,
suiteFailures, suiteFailures,
suiteEndTime, suiteEndTime];
fputs([suiteEndString UTF8String], stderr);
fflush(stderr);
}
@end
... ...
//
// GTMIPhoneUnitTestMain.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 "GTMDefines.h"
#if !GTM_IPHONE_SDK
#error GTMIPhoneUnitTestMain for iPhone only
#endif
#import <UIKit/UIKit.h>
// Creates an application that runs all tests from classes extending
// SenTestCase, outputs results and test run time, and terminates right
// afterwards.
int main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, @"GTMIPhoneUnitTestDelegate");
[pool release];
return retVal;
}
... ...
//
// GTMSenTestCase.h
//
// Copyright 2007-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.
//
// Portions of this file fall under the following license, marked with
// SENTE_BEGIN - SENTE_END
//
// Copyright (c) 1997-2005, Sen:te (Sente SA). All rights reserved.
//
// Use of this source code is governed by the following license:
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
// (1) Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
//
// (2) Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL Sente SA OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
// OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// Note: this license is equivalent to the FreeBSD license.
//
// This notice may not be removed from this file.
// Some extra test case macros that would have been convenient for SenTestingKit
// to provide. I didn't stick GTM in front of the Macro names, so that they would
// be easy to remember.
#import "GTMDefines.h"
#if (!GTM_IPHONE_SDK)
#import <SenTestingKit/SenTestingKit.h>
#else
#import <Foundation/Foundation.h>
NSString *STComposeString(NSString *, ...);
#endif
// Generates a failure when a1 != noErr
// Args:
// a1: should be either an OSErr or an OSStatus
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNoErr(a1, description, ...) \
do { \
@try {\
OSStatus a1value = (a1); \
if (a1value != noErr) { \
NSString *_expression = [NSString stringWithFormat:@"Expected noErr, got %ld for (%s)", a1value, #a1]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 != a2
// Args:
// a1: received value. Should be either an OSErr or an OSStatus
// a2: expected value. Should be either an OSErr or an OSStatus
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertErr(a1, a2, description, ...) \
do { \
@try {\
OSStatus a1value = (a1); \
OSStatus a2value = (a2); \
if (a1value != a2value) { \
NSString *_expression = [NSString stringWithFormat:@"Expected %s(%ld) but got %ld for (%s)", #a2, a2value, a1value, #a1]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == noErr fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is NULL
// Args:
// a1: should be a pointer (use STAssertNotNil for an object)
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNotNULL(a1, description, ...) \
do { \
@try {\
const void* a1value = (a1); \
if (a1value == NULL) { \
NSString *_expression = [NSString stringWithFormat:@"(%s) != NULL", #a1]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != NULL fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is not NULL
// Args:
// a1: should be a pointer (use STAssertNil for an object)
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNULL(a1, description, ...) \
do { \
@try {\
const void* a1value = (a1); \
if (a1value != NULL) { \
NSString *_expression = [NSString stringWithFormat:@"(%s) == NULL", #a1]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) == NULL fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is unequal to a2. This test is for C scalars,
// structs and unions.
// Args:
// a1: argument 1
// a2: argument 2
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNotEquals(a1, a2, description, ...) \
do { \
@try {\
if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
} else { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
if ([a1encoded isEqualToValue:a2encoded]) { \
NSString *_expression = [NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat:@"(%s) != (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is equal to a2. This test is for objects.
// Args:
// a1: argument 1. object.
// a2: argument 2. object.
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNotEqualObjects(a1, a2, desc, ...) \
do { \
@try {\
id a1value = (a1); \
id a2value = (a2); \
if ( (@encode(__typeof__(a1value)) == @encode(id)) && \
(@encode(__typeof__(a2value)) == @encode(id)) && \
![(id)a1value isEqual:(id)a2value] ) continue; \
NSString *_expression = [NSString stringWithFormat:@"%s('%@') != %s('%@')", #a1, [a1 description], #a2, [a2 description]]; \
if (desc) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(desc, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(desc, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is not 'op' to a2. This test is for C scalars.
// Args:
// a1: argument 1
// a2: argument 2
// op: operation
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertOperation(a1, a2, op, description, ...) \
do { \
@try {\
if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
} else { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
if (!(a1value op a2value)) { \
double a1DoubleValue = a1value; \
double a2DoubleValue = a2value; \
NSString *_expression = [NSString stringWithFormat:@"%s (%lg) %s %s (%lg)", #a1, a1DoubleValue, #op, #a2, a2DoubleValue]; \
if (description) { \
_expression = [NSString stringWithFormat:@"%@: %@", _expression, STComposeString(description, ##__VA_ARGS__)]; \
} \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:_expression]]; \
} \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException \
failureInRaise:[NSString stringWithFormat:@"(%s) %s (%s)", #a1, #op, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when a1 is not > a2. This test is for C scalars.
// Args:
// a1: argument 1
// a2: argument 2
// op: operation
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertGreaterThan(a1, a2, description, ...) \
STAssertOperation(a1, a2, >, description, ##__VA_ARGS__)
// Generates a failure when a1 is not >= a2. This test is for C scalars.
// Args:
// a1: argument 1
// a2: argument 2
// op: operation
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertGreaterThanOrEqual(a1, a2, description, ...) \
STAssertOperation(a1, a2, >=, description, ##__VA_ARGS__)
// Generates a failure when a1 is not < a2. This test is for C scalars.
// Args:
// a1: argument 1
// a2: argument 2
// op: operation
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertLessThan(a1, a2, description, ...) \
STAssertOperation(a1, a2, <, description, ##__VA_ARGS__)
// Generates a failure when a1 is not <= a2. This test is for C scalars.
// Args:
// a1: argument 1
// a2: argument 2
// op: operation
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertLessThanOrEqual(a1, a2, description, ...) \
STAssertOperation(a1, a2, <=, description, ##__VA_ARGS__)
// Generates a failure when string a1 is not equal to string a2. This call
// differs from STAssertEqualObjects in that strings that are different in
// composition (precomposed vs decomposed) will compare equal if their final
// representation is equal.
// ex O + umlaut decomposed is the same as O + umlaut composed.
// Args:
// a1: string 1
// a2: string 2
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertEqualStrings(a1, a2, description, ...) \
do { \
@try {\
id a1value = (a1); \
id a2value = (a2); \
if (a1value == a2value) continue; \
if ([a1value isKindOfClass:[NSString class]] && \
[a2value isKindOfClass:[NSString class]] && \
[a1value compare:a2value options:0] == NSOrderedSame) continue; \
[self failWithException:[NSException failureInEqualityBetweenObject: a1value \
andObject: a2value \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when string a1 is equal to string a2. This call
// differs from STAssertEqualObjects in that strings that are different in
// composition (precomposed vs decomposed) will compare equal if their final
// representation is equal.
// ex O + umlaut decomposed is the same as O + umlaut composed.
// Args:
// a1: string 1
// a2: string 2
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNotEqualStrings(a1, a2, description, ...) \
do { \
@try {\
id a1value = (a1); \
id a2value = (a2); \
if ([a1value isKindOfClass:[NSString class]] && \
[a2value isKindOfClass:[NSString class]] && \
[a1value compare:a2value options:0] != NSOrderedSame) continue; \
[self failWithException:[NSException failureInEqualityBetweenObject: a1value \
andObject: a2value \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when c-string a1 is not equal to c-string a2.
// Args:
// a1: string 1
// a2: string 2
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertEqualCStrings(a1, a2, description, ...) \
do { \
@try {\
const char* a1value = (a1); \
const char* a2value = (a2); \
if (a1value == a2value) continue; \
if (strcmp(a1value, a2value) == 0) continue; \
[self failWithException:[NSException failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \
andObject: [NSString stringWithUTF8String:a2value] \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
// Generates a failure when c-string a1 is equal to c-string a2.
// Args:
// a1: string 1
// a2: string 2
// description: A format string as in the printf() function. Can be nil or
// an empty string but must be present.
// ...: A variable number of arguments to the format string. Can be absent.
#define STAssertNotEqualCStrings(a1, a2, description, ...) \
do { \
@try {\
const char* a1value = (a1); \
const char* a2value = (a2); \
if (strcmp(a1value, a2value) != 0) continue; \
[self failWithException:[NSException failureInEqualityBetweenObject: [NSString stringWithUTF8String:a1value] \
andObject: [NSString stringWithUTF8String:a2value] \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
#if GTM_IPHONE_SDK
// SENTE_BEGIN
/*" Generates a failure when !{ [a1 isEqualTo:a2] } is false
(or one is nil and the other is not).
_{a1 The object on the left.}
_{a2 The object on the right.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertEqualObjects(a1, a2, description, ...) \
do { \
@try {\
id a1value = (a1); \
id a2value = (a2); \
if (a1value == a2value) continue; \
if ( (@encode(__typeof__(a1value)) == @encode(id)) && \
(@encode(__typeof__(a2value)) == @encode(id)) && \
[(id)a1value isEqual: (id)a2value] ) continue; \
[self failWithException:[NSException failureInEqualityBetweenObject: a1value \
andObject: a2value \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
/*" Generates a failure when a1 is not equal to a2. This test is for
C scalars, structs and unions.
_{a1 The argument on the left.}
_{a2 The argument on the right.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertEquals(a1, a2, description, ...) \
do { \
@try {\
if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
} else { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
NSValue *a1encoded = [NSValue value:&a1value withObjCType: @encode(__typeof__(a1))]; \
NSValue *a2encoded = [NSValue value:&a2value withObjCType: @encode(__typeof__(a2))]; \
if (![a1encoded isEqualToValue:a2encoded]) { \
[self failWithException:[NSException failureInEqualityBetweenValue: a1encoded \
andValue: a2encoded \
withAccuracy: nil \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
#define STAbsoluteDifference(left,right) (MAX(left,right)-MIN(left,right))
/*" Generates a failure when a1 is not equal to a2 within + or - accuracy is false.
This test is for scalars such as floats and doubles where small differences
could make these items not exactly equal, but also works for all scalars.
_{a1 The scalar on the left.}
_{a2 The scalar on the right.}
_{accuracy The maximum difference between a1 and a2 for these values to be
considered equal.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertEqualsWithAccuracy(a1, a2, accuracy, description, ...) \
do { \
@try {\
if (@encode(__typeof__(a1)) != @encode(__typeof__(a2))) { \
[self failWithException:[NSException failureInFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:[@"Type mismatch -- " stringByAppendingString:STComposeString(description, ##__VA_ARGS__)]]]; \
} else { \
__typeof__(a1) a1value = (a1); \
__typeof__(a2) a2value = (a2); \
__typeof__(accuracy) accuracyvalue = (accuracy); \
if (STAbsoluteDifference(a1value, a2value) > accuracyvalue) { \
NSValue *a1encoded = [NSValue value:&a1value withObjCType:@encode(__typeof__(a1))]; \
NSValue *a2encoded = [NSValue value:&a2value withObjCType:@encode(__typeof__(a2))]; \
NSValue *accuracyencoded = [NSValue value:&accuracyvalue withObjCType:@encode(__typeof__(accuracy))]; \
[self failWithException:[NSException failureInEqualityBetweenValue: a1encoded \
andValue: a2encoded \
withAccuracy: accuracyencoded \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == (%s)", #a1, #a2] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
/*" Generates a failure unconditionally.
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STFail(description, ...) \
[self failWithException:[NSException failureInFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]
/*" Generates a failure when a1 is not nil.
_{a1 An object.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertNil(a1, description, ...) \
do { \
@try {\
id a1value = (a1); \
if (a1value != nil) { \
NSString *_a1 = [NSString stringWithUTF8String: #a1]; \
NSString *_expression = [NSString stringWithFormat:@"((%@) == nil)", _a1]; \
[self failWithException:[NSException failureInCondition: _expression \
isTrue: NO \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) == nil fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
/*" Generates a failure when a1 is nil.
_{a1 An object.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertNotNil(a1, description, ...) \
do { \
@try {\
id a1value = (a1); \
if (a1value == nil) { \
NSString *_a1 = [NSString stringWithUTF8String: #a1]; \
NSString *_expression = [NSString stringWithFormat:@"((%@) != nil)", _a1]; \
[self failWithException:[NSException failureInCondition: _expression \
isTrue: NO \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
}\
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) != nil fails", #a1] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while(0)
/*" Generates a failure when expression evaluates to false.
_{expr The expression that is tested.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertTrue(expr, description, ...) \
do { \
BOOL _evaluatedExpression = (expr);\
if (!_evaluatedExpression) {\
NSString *_expression = [NSString stringWithUTF8String: #expr];\
[self failWithException:[NSException failureInCondition: _expression \
isTrue: NO \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} while (0)
/*" Generates a failure when expression evaluates to false and in addition will
generate error messages if an exception is encountered.
_{expr The expression that is tested.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertTrueNoThrow(expr, description, ...) \
do { \
@try {\
BOOL _evaluatedExpression = (expr);\
if (!_evaluatedExpression) {\
NSString *_expression = [NSString stringWithUTF8String: #expr];\
[self failWithException:[NSException failureInCondition: _expression \
isTrue: NO \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) ", #expr] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while (0)
/*" Generates a failure when the expression evaluates to true.
_{expr The expression that is tested.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertFalse(expr, description, ...) \
do { \
BOOL _evaluatedExpression = (expr);\
if (_evaluatedExpression) {\
NSString *_expression = [NSString stringWithUTF8String: #expr];\
[self failWithException:[NSException failureInCondition: _expression \
isTrue: YES \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} while (0)
/*" Generates a failure when the expression evaluates to true and in addition
will generate error messages if an exception is encountered.
_{expr The expression that is tested.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertFalseNoThrow(expr, description, ...) \
do { \
@try {\
BOOL _evaluatedExpression = (expr);\
if (_evaluatedExpression) {\
NSString *_expression = [NSString stringWithUTF8String: #expr];\
[self failWithException:[NSException failureInCondition: _expression \
isTrue: YES \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} \
} \
@catch (id anException) {\
[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"!(%s) ", #expr] \
exception:anException \
inFile:[NSString stringWithUTF8String:__FILE__] \
atLine:__LINE__ \
withDescription:STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while (0)
/*" Generates a failure when expression does not throw an exception.
_{expression The expression that is evaluated.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.
"*/
#define STAssertThrows(expr, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (id anException) { \
continue; \
}\
[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: nil \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
} while (0)
/*" Generates a failure when expression does not throw an exception of a
specific class.
_{expression The expression that is evaluated.}
_{specificException The specified class of the exception.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertThrowsSpecific(expr, specificException, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (specificException *anException) { \
continue; \
}\
@catch (id anException) {\
NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
continue; \
}\
NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: nil \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
} while (0)
/*" Generates a failure when expression does not throw an exception of a
specific class with a specific name. Useful for those frameworks like
AppKit or Foundation that throw generic NSException w/specific names
(NSInvalidArgumentException, etc).
_{expression The expression that is evaluated.}
_{specificException The specified class of the exception.}
_{aName The name of the specified exception.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (specificException *anException) { \
if ([aName isEqualToString: [anException name]]) continue; \
NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\
[self failWithException: \
[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
continue; \
}\
@catch (id anException) {\
NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
[self failWithException: \
[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
continue; \
}\
NSString *_descrip = STComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\
[self failWithException: \
[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: nil \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
} while (0)
/*" Generates a failure when expression does throw an exception.
_{expression The expression that is evaluated.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertNoThrow(expr, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (id anException) { \
[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
} while (0)
/*" Generates a failure when expression does throw an exception of the specitied
class. Any other exception is okay (i.e. does not generate a failure).
_{expression The expression that is evaluated.}
_{specificException The specified class of the exception.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertNoThrowSpecific(expr, specificException, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (specificException *anException) { \
[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(description, ##__VA_ARGS__)]]; \
}\
@catch (id anythingElse) {\
; \
}\
} while (0)
/*" Generates a failure when expression does throw an exception of a
specific class with a specific name. Useful for those frameworks like
AppKit or Foundation that throw generic NSException w/specific names
(NSInvalidArgumentException, etc).
_{expression The expression that is evaluated.}
_{specificException The specified class of the exception.}
_{aName The name of the specified exception.}
_{description A format string as in the printf() function. Can be nil or
an empty string but must be present.}
_{... A variable number of arguments to the format string. Can be absent.}
"*/
#define STAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \
do { \
@try { \
(expr);\
} \
@catch (specificException *anException) { \
if ([aName isEqualToString: [anException name]]) { \
NSString *_descrip = STComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\
[self failWithException: \
[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \
exception: anException \
inFile: [NSString stringWithUTF8String:__FILE__] \
atLine: __LINE__ \
withDescription: STComposeString(_descrip, ##__VA_ARGS__)]]; \
} \
continue; \
}\
@catch (id anythingElse) {\
; \
}\
} while (0)
@interface NSException (GTMSenTestAdditions)
+ (NSException *)failureInFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ...;
+ (NSException *)failureInCondition:(NSString *)condition
isTrue:(BOOL)isTrue
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ...;
+ (NSException *)failureInEqualityBetweenObject:(id)left
andObject:(id)right
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ...;
+ (NSException *)failureInEqualityBetweenValue:(NSValue *)left
andValue:(NSValue *)right
withAccuracy:(NSValue *)accuracy
inFile:(NSString *)filename
atLine:(int) ineNumber
withDescription:(NSString *)formatString, ...;
+ (NSException *)failureInRaise:(NSString *)expression
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ...;
+ (NSException *)failureInRaise:(NSString *)expression
exception:(NSException *)exception
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ...;
@end
// SENTE_END
@interface NSObject (GTMSenTestAdditions)
- (void)failWithException:(NSException*)exception;
@end
@interface SenTestCase : NSObject {
SEL currentSelector_;
}
- (void)setUp;
- (void)invokeTest;
- (void)tearDown;
- (void)performTest:(SEL)sel;
@end
CF_EXPORT NSString * const SenTestFailureException;
#endif // GTM_IPHONE_SDK
// All unittest cases in GTM should inherit from GTMTestCase. It makes sure
// to set up our logging system correctly to verify logging calls.
// See GTMUnitTestDevLog.h for details
@interface GTMTestCase : SenTestCase
@end
... ...
//
// GTMSenTestCase.m
//
// Copyright 2007-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"
#if GTM_IPHONE_SDK
#import <stdarg.h>
@implementation NSException (GTMSenTestAdditions)
+ (NSException *)failureInFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"%@:%d: error: %@", filename, lineNumber, reason];
return [NSException exceptionWithName:SenTestFailureException
reason:reason
userInfo:nil];
}
+ (NSException *)failureInCondition:(NSString *)condition
isTrue:(BOOL)isTrue
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"condition '%@' is %s : %@",
condition, isTrue ? "TRUE" : "FALSE", reason];
return [self failureInFile:filename atLine:lineNumber withDescription:reason];
}
+ (NSException *)failureInEqualityBetweenObject:(id)left
andObject:(id)right
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"%@ != %@ : %@",
left, right, reason];
return [self failureInFile:filename atLine:lineNumber withDescription:reason];
}
+ (NSException *)failureInEqualityBetweenValue:(NSValue *)left
andValue:(NSValue *)right
withAccuracy:(NSValue *)accuracy
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"%@ != %@ with accuracy %@ : %@",
left, right, accuracy, reason];
return [self failureInFile:filename atLine:lineNumber withDescription:reason];
}
+ (NSException *)failureInRaise:(NSString *)expression
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"failure in raise %@ : %@",
expression, reason];
return [self failureInFile:filename atLine:lineNumber withDescription:reason];
}
+ (NSException *)failureInRaise:(NSString *)expression
exception:(NSException *)exception
inFile:(NSString *)filename
atLine:(int)lineNumber
withDescription:(NSString *)formatString, ... {
va_list vl;
va_start(vl, formatString);
NSString *reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
reason = [NSString stringWithFormat:@"failure in raise %@ (%@) : %@",
expression, exception, reason];
return [self failureInFile:filename atLine:lineNumber withDescription:reason];
}
@end
@implementation NSObject (GTMSenTestAdditions)
- (void)failWithException:(NSException*)exception {
[exception raise];
}
@end
NSString *STComposeString(NSString *formatString, ...) {
NSString *reason = @"";
if (formatString) {
va_list vl;
va_start(vl, formatString);
reason = [[[NSString alloc] initWithFormat:formatString arguments:vl] autorelease];
va_end(vl);
}
return reason;
}
NSString * const SenTestFailureException = @"SenTestFailureException";
@interface SenTestCase (SenTestCasePrivate)
// our method of logging errors
- (void)printError:(NSString *)error;
@end
@implementation SenTestCase
- (void)setUp {
}
- (void)performTest:(SEL)sel {
currentSelector_ = sel;
@try {
[self invokeTest];
} @catch (NSException *exception) {
[self printError:[exception reason]];
[exception raise];
}
}
- (void)printError:(NSString *)error {
if ([error rangeOfString:@"error:"].location == NSNotFound) {
fprintf(stderr, "error: %s\n", [error UTF8String]);
} else {
fprintf(stderr, "%s\n", [error UTF8String]);
}
fflush(stderr);
}
- (void)invokeTest {
NSException *e = nil;
@try {
// Wrap things in autorelease pools because they may
// have an STMacro in their dealloc which may get called
// when the pool is cleaned up
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@try {
[self setUp];
@try {
[self performSelector:currentSelector_];
} @catch (NSException *exception) {
e = [exception retain];
[self printError:[exception reason]];
}
[self tearDown];
} @catch (NSException *exception) {
e = [exception retain];
[self printError:[exception reason]];
}
[pool release];
} @catch (NSException *exception) {
e = [exception retain];
[self printError:[exception reason]];
}
if (e) {
[e autorelease];
[e raise];
}
}
- (void)tearDown {
}
@end
#endif
@implementation GTMTestCase : SenTestCase
- (void) invokeTest {
Class devLogClass = NSClassFromString(@"GTMUnitTestDevLog");
if (devLogClass) {
[devLogClass performSelector:@selector(enableTracking)];
[devLogClass performSelector:@selector(verifyNoMoreLogsExpected)];
}
[super invokeTest];
if (devLogClass) {
[devLogClass performSelector:@selector(verifyNoMoreLogsExpected)];
[devLogClass performSelector:@selector(disableTracking)];
}
}
@end
... ...
... ... @@ -43,6 +43,58 @@
23A0ABAA0EB923AF003A4521 /* RMLatLong.h in Headers */ = {isa = PBXBuildFile; fileRef = 23A0ABA90EB923AF003A4521 /* RMLatLong.h */; };
2B5682720F68E36000E8DF40 /* RMOpenAerialMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */; };
2B5682730F68E36000E8DF40 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; };
2BEC60170F8AC6B8008FB858 /* GTMIPhoneUnitTestDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF306C30F8ABCA4007014EE /* GTMIPhoneUnitTestDelegate.m */; };
2BEC60180F8AC6B9008FB858 /* GTMIPhoneUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF306C40F8ABCA4007014EE /* GTMIPhoneUnitTestMain.m */; };
2BEC60190F8AC6BA008FB858 /* GTMSenTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 2BF306C60F8ABCA4007014EE /* GTMSenTestCase.m */; };
2BEC602C0F8AC6FC008FB858 /* FMDatabase.m in Sources */ = {isa = PBXBuildFile; fileRef = B8474B8E0EB40094006A0BC1 /* FMDatabase.m */; };
2BEC602D0F8AC6FE008FB858 /* FMDatabaseAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = B8474B900EB40094006A0BC1 /* FMDatabaseAdditions.m */; };
2BEC602F0F8AC700008FB858 /* FMResultSet.m in Sources */ = {isa = PBXBuildFile; fileRef = B8474B930EB40094006A0BC1 /* FMResultSet.m */; };
2BEC60300F8AC70C008FB858 /* RMAbstractMercatorWebSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A967510E8412930031BA75 /* RMAbstractMercatorWebSource.m */; };
2BEC60310F8AC70D008FB858 /* RMCachedTileSource.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C974C90E8A9C30007D16AD /* RMCachedTileSource.m */; };
2BEC60320F8AC70E008FB858 /* RMCloudMadeMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = B885ABB10EBB1332002206AB /* RMCloudMadeMapSource.m */; };
2BEC60330F8AC70F008FB858 /* RMConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = 126692A00EB75C0A00E002D5 /* RMConfiguration.m */; };
2BEC60340F8AC712008FB858 /* RMCoreAnimationRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64BE0E80E73F001663B6 /* RMCoreAnimationRenderer.m */; };
2BEC60350F8AC713008FB858 /* RMDatabaseCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B8474B990EB40094006A0BC1 /* RMDatabaseCache.m */; };
2BEC60360F8AC715008FB858 /* RMFileTileImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64DF0E80E73F001663B6 /* RMFileTileImage.m */; };
2BEC60370F8AC718008FB858 /* RMFoundation.c in Sources */ = {isa = PBXBuildFile; fileRef = 23A0AAE80EB90A99003A4521 /* RMFoundation.c */; };
2BEC60380F8AC71A008FB858 /* RMFractalTileProjection.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64EA0E80E73F001663B6 /* RMFractalTileProjection.m */; };
2BEC60390F8AC71C008FB858 /* RMGeoHash.m in Sources */ = {isa = PBXBuildFile; fileRef = F5C12D290F8A86CA00A894D2 /* RMGeoHash.m */; };
2BEC603A0F8AC71D008FB858 /* RMLayerSet.m in Sources */ = {isa = PBXBuildFile; fileRef = B8FA92180E9315EC003A9FE6 /* RMLayerSet.m */; };
2BEC603B0F8AC71E008FB858 /* RMMapContents.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C974B70E8A280A007D16AD /* RMMapContents.m */; };
2BEC603C0F8AC71F008FB858 /* RMMapLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F3FC600EA2B382004D8F85 /* RMMapLayer.m */; };
2BEC603D0F8AC722008FB858 /* RMMapRenderer.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64CB0E80E73F001663B6 /* RMMapRenderer.m */; };
2BEC603E0F8AC723008FB858 /* RMMapView.m in Sources */ = {isa = PBXBuildFile; fileRef = B8C9746A0E8A1A50007D16AD /* RMMapView.m */; };
2BEC603F0F8AC724008FB858 /* RMMarker.m in Sources */ = {isa = PBXBuildFile; fileRef = B8F3FC630EA2E792004D8F85 /* RMMarker.m */; };
2BEC60400F8AC725008FB858 /* RMMarkerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 090C948C0EC23FCD003AEE25 /* RMMarkerManager.m */; };
2BEC60410F8AC726008FB858 /* RMMarkerStyle.m in Sources */ = {isa = PBXBuildFile; fileRef = 1296F5600EB8743500FF25E0 /* RMMarkerStyle.m */; };
2BEC60420F8AC728008FB858 /* RMMarkerStyles.m in Sources */ = {isa = PBXBuildFile; fileRef = 1296F5630EB8745300FF25E0 /* RMMarkerStyles.m */; };
2BEC60430F8AC729008FB858 /* RMMemoryCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64D30E80E73F001663B6 /* RMMemoryCache.m */; };
2BEC60440F8AC729008FB858 /* RMMercatorToScreenProjection.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64C90E80E73F001663B6 /* RMMercatorToScreenProjection.m */; };
2BEC60450F8AC72B008FB858 /* RMOpenAerialMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */; };
2BEC60460F8AC72C008FB858 /* RMOpenStreetMapsSource.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64EE0E80E73F001663B6 /* RMOpenStreetMapsSource.m */; };
2BEC60470F8AC72E008FB858 /* RMPath.m in Sources */ = {isa = PBXBuildFile; fileRef = B8CEB1C40ED5A3480014C431 /* RMPath.m */; };
2BEC60480F8AC72F008FB858 /* RMPixel.c in Sources */ = {isa = PBXBuildFile; fileRef = B83E64B70E80E73F001663B6 /* RMPixel.c */; };
2BEC60490F8AC738008FB858 /* RMProjection.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64E40E80E73F001663B6 /* RMProjection.m */; };
2BEC604A0F8AC739008FB858 /* RMTile.c in Sources */ = {isa = PBXBuildFile; fileRef = B83E64D70E80E73F001663B6 /* RMTile.c */; };
2BEC604B0F8AC73A008FB858 /* RMTileCache.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64D10E80E73F001663B6 /* RMTileCache.m */; };
2BEC604C0F8AC73C008FB858 /* RMTileCacheDAO.m in Sources */ = {isa = PBXBuildFile; fileRef = B8474B970EB40094006A0BC1 /* RMTileCacheDAO.m */; };
2BEC604D0F8AC73D008FB858 /* RMTiledLayerController.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64C50E80E73F001663B6 /* RMTiledLayerController.m */; };
2BEC604E0F8AC73D008FB858 /* RMTileImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64D90E80E73F001663B6 /* RMTileImage.m */; };
2BEC604F0F8AC73E008FB858 /* RMTileImageSet.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64E10E80E73F001663B6 /* RMTileImageSet.m */; };
2BEC60500F8AC73F008FB858 /* RMTileLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64C70E80E73F001663B6 /* RMTileLoader.m */; };
2BEC60510F8AC740008FB858 /* RMTileProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64DB0E80E73F001663B6 /* RMTileProxy.m */; };
2BEC60520F8AC741008FB858 /* RMTransform.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64E60E80E73F001663B6 /* RMTransform.m */; };
2BEC60530F8AC742008FB858 /* RMVirtualEarthSource.m in Sources */ = {isa = PBXBuildFile; fileRef = C7A9675D0E84134B0031BA75 /* RMVirtualEarthSource.m */; };
2BEC60540F8AC744008FB858 /* RMWebTileImage.m in Sources */ = {isa = PBXBuildFile; fileRef = B83E64DD0E80E73F001663B6 /* RMWebTileImage.m */; };
2BEC60550F8AC745008FB858 /* RMYahooMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 96FE8E350F72D01B00A11CF0 /* RMYahooMapSource.m */; };
2BEC60960F8ACBF1008FB858 /* libProj4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 38D818500F6F67B90034598B /* libProj4.a */; };
2BEC612D0F8ACC1E008FB858 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B83E65590E80E7EB001663B6 /* CoreFoundation.framework */; };
2BEC612E0F8ACC1E008FB858 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765A40DF7441C002DB57D /* CoreGraphics.framework */; };
2BEC612F0F8ACC1E008FB858 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B83E65630E80E81C001663B6 /* CoreLocation.framework */; };
2BEC61300F8ACC1F008FB858 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; };
2BEC61310F8ACC21008FB858 /* libsqlite3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B8474BC00EB4019A006A0BC1 /* libsqlite3.dylib */; };
2BEC61320F8ACC24008FB858 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B83E65680E80E830001663B6 /* QuartzCore.framework */; };
2BEC61330F8ACC25008FB858 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; };
3849889C0F6F758100496293 /* libProj4.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 38D818500F6F67B90034598B /* libProj4.a */; };
96FE8E360F72D01B00A11CF0 /* RMYahooMapSource.h in Headers */ = {isa = PBXBuildFile; fileRef = 96FE8E340F72D01B00A11CF0 /* RMYahooMapSource.h */; };
96FE8E370F72D01B00A11CF0 /* RMYahooMapSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 96FE8E350F72D01B00A11CF0 /* RMYahooMapSource.m */; };
... ... @@ -127,6 +179,13 @@
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
2BEC606C0F8AC7B3008FB858 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B83E654A0E80E7A8001663B6 /* Proj4.xcodeproj */;
proxyType = 1;
remoteGlobalIDString = D2AAC07D0554694100DB518D /* Proj4 */;
remoteInfo = Proj4;
};
38D8184F0F6F67B90034598B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = B83E654A0E80E7A8001663B6 /* Proj4.xcodeproj */;
... ... @@ -164,6 +223,16 @@
2B2BD41E0F79A95500B8B9A7 /* routeme.doxygen */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = routeme.doxygen; sourceTree = "<group>"; };
2B5682700F68E36000E8DF40 /* RMOpenAerialMapSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RMOpenAerialMapSource.h; sourceTree = "<group>"; };
2B5682710F68E36000E8DF40 /* RMOpenAerialMapSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RMOpenAerialMapSource.m; sourceTree = "<group>"; };
2BEC61AB0F8AD20E008FB858 /* UnitTests_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UnitTests_Prefix.pch; sourceTree = "<group>"; };
2BF306C20F8ABCA4007014EE /* GTMIPhoneUnitTestDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMIPhoneUnitTestDelegate.h; sourceTree = "<group>"; };
2BF306C30F8ABCA4007014EE /* GTMIPhoneUnitTestDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMIPhoneUnitTestDelegate.m; sourceTree = "<group>"; };
2BF306C40F8ABCA4007014EE /* GTMIPhoneUnitTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMIPhoneUnitTestMain.m; sourceTree = "<group>"; };
2BF306C50F8ABCA4007014EE /* GTMSenTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMSenTestCase.h; sourceTree = "<group>"; };
2BF306C60F8ABCA4007014EE /* GTMSenTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMSenTestCase.m; sourceTree = "<group>"; };
2BF306CC0F8ABCCE007014EE /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = "<group>"; };
2BF306FB0F8ABE7E007014EE /* RunIPhoneUnitTest.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = RunIPhoneUnitTest.sh; sourceTree = "<group>"; };
2BF3078F0F8AC5C0007014EE /* RM Unit Tests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "RM Unit Tests.app"; sourceTree = BUILT_PRODUCTS_DIR; };
2BF307910F8AC5C0007014EE /* RM Unit Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "RM Unit Tests-Info.plist"; sourceTree = "<group>"; };
32CA4F630368D1EE00C91783 /* MapView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapView_Prefix.pch; sourceTree = "<group>"; };
3866784C0F6B9B9200C56B17 /* MapView.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapView.framework; path = build/MapView.framework; sourceTree = "<group>"; };
38DAD5490F739BAD00D1DF51 /* Canonical.framework.tar */ = {isa = PBXFileReference; lastKnownFileType = archive.tar; path = Canonical.framework.tar; sourceTree = "<group>"; };
... ... @@ -259,6 +328,21 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
2BF3078D0F8AC5C0007014EE /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
2BEC60960F8ACBF1008FB858 /* libProj4.a in Frameworks */,
2BEC612D0F8ACC1E008FB858 /* CoreFoundation.framework in Frameworks */,
2BEC612E0F8ACC1E008FB858 /* CoreGraphics.framework in Frameworks */,
2BEC612F0F8ACC1E008FB858 /* CoreLocation.framework in Frameworks */,
2BEC61300F8ACC1F008FB858 /* Foundation.framework in Frameworks */,
2BEC61310F8ACC21008FB858 /* libsqlite3.dylib in Frameworks */,
2BEC61320F8ACC24008FB858 /* QuartzCore.framework in Frameworks */,
2BEC61330F8ACC25008FB858 /* UIKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B8C9744F0E8A19B2007D16AD /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
... ... @@ -290,6 +374,7 @@
children = (
B8C974590E8A19B2007D16AD /* libMapView.a */,
3866784C0F6B9B9200C56B17 /* MapView.framework */,
2BF3078F0F8AC5C0007014EE /* RM Unit Tests.app */,
);
name = Products;
sourceTree = "<group>";
... ... @@ -297,15 +382,14 @@
29B97314FDCFA39411CA2CEA /* CustomTemplate */ = {
isa = PBXGroup;
children = (
2BEC61AB0F8AD20E008FB858 /* UnitTests_Prefix.pch */,
2BF0E4540F73119C0095A926 /* Documentation */,
B8C9740D0E8A196E007D16AD /* Map */,
B83E67570E80F3FB001663B6 /* Resources */,
29B97323FDCFA39411CA2CEA /* Frameworks */,
19C28FACFE9D520D11CA2CBB /* Products */,
2B2BD42E0F79A9A500B8B9A7 /* Static Library Build */,
B86F26E10E877802007A3773 /* DesktopMapView-Info.plist */,
32CA4F630368D1EE00C91783 /* MapView_Prefix.pch */,
B8474BC00EB4019A006A0BC1 /* libsqlite3.dylib */,
);
name = CustomTemplate;
sourceTree = "<group>";
... ... @@ -313,6 +397,7 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
B8474BC00EB4019A006A0BC1 /* libsqlite3.dylib */,
B83E65590E80E7EB001663B6 /* CoreFoundation.framework */,
B83E65630E80E81C001663B6 /* CoreLocation.framework */,
B83E65680E80E830001663B6 /* QuartzCore.framework */,
... ... @@ -342,6 +427,21 @@
name = Documentation;
sourceTree = "<group>";
};
2BF306BF0F8ABC35007014EE /* Google Toolbox for Mac (unit testing) */ = {
isa = PBXGroup;
children = (
2BF306FB0F8ABE7E007014EE /* RunIPhoneUnitTest.sh */,
2BF306CC0F8ABCCE007014EE /* GTMDefines.h */,
2BF306C20F8ABCA4007014EE /* GTMIPhoneUnitTestDelegate.h */,
2BF306C30F8ABCA4007014EE /* GTMIPhoneUnitTestDelegate.m */,
2BF306C40F8ABCA4007014EE /* GTMIPhoneUnitTestMain.m */,
2BF306C50F8ABCA4007014EE /* GTMSenTestCase.h */,
2BF306C60F8ABCA4007014EE /* GTMSenTestCase.m */,
);
name = "Google Toolbox for Mac (unit testing)";
path = ..;
sourceTree = "<group>";
};
38D8184C0F6F67B90034598B /* Products */ = {
isa = PBXGroup;
children = (
... ... @@ -450,6 +550,8 @@
isa = PBXGroup;
children = (
8D1107310486CEB800E47090 /* Info.plist */,
B86F26E10E877802007A3773 /* DesktopMapView-Info.plist */,
2BF307910F8AC5C0007014EE /* RM Unit Tests-Info.plist */,
);
name = Resources;
sourceTree = "<group>";
... ... @@ -531,6 +633,7 @@
B83E64B80E80E73F001663B6 /* Renderers */,
B86F26A80E8742ED007A3773 /* Markers and other layers */,
1266929E0EB75BEA00E002D5 /* Configuration */,
2BF306BF0F8ABC35007014EE /* Google Toolbox for Mac (unit testing) */,
B8474C610EB53A01006A0BC1 /* Resources */,
);
path = Map;
... ... @@ -621,6 +724,25 @@
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
2BF3078E0F8AC5C0007014EE /* RM Unit Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 2BF307940F8AC5C1007014EE /* Build configuration list for PBXNativeTarget "RM Unit Tests" */;
buildPhases = (
2BF3078B0F8AC5C0007014EE /* Resources */,
2BF3078C0F8AC5C0007014EE /* Sources */,
2BF3078D0F8AC5C0007014EE /* Frameworks */,
2BF307960F8AC60C007014EE /* ShellScript */,
);
buildRules = (
);
dependencies = (
2BEC606D0F8AC7B3008FB858 /* PBXTargetDependency */,
);
name = "RM Unit Tests";
productName = "RM Unit Tests";
productReference = 2BF3078F0F8AC5C0007014EE /* RM Unit Tests.app */;
productType = "com.apple.product-type.application";
};
B8C974130E8A19B2007D16AD /* MapView */ = {
isa = PBXNativeTarget;
buildConfigurationList = B8C974560E8A19B2007D16AD /* Build configuration list for PBXNativeTarget "MapView" */;
... ... @@ -660,6 +782,7 @@
B8C974130E8A19B2007D16AD /* MapView */,
386676D40F6B73AC00C56B17 /* MapView-framework */,
2B2BD43A0F79AA1B00B8B9A7 /* Doxygen-Documentation */,
2BF3078E0F8AC5C0007014EE /* RM Unit Tests */,
);
};
/* End PBXProject section */
... ... @@ -674,6 +797,16 @@
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
2BF3078B0F8AC5C0007014EE /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
2B2BD4390F79AA1B00B8B9A7 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
... ... @@ -688,6 +821,19 @@
shellPath = /bin/sh;
shellScript = "# shell script goes here\n# Append the proper input/output directories and docset info to the config file.\n# This works even though values are assigned higher up in the file. Easier than sed.\n\ncp $SOURCE_ROOT/routeme.doxygen $TEMP_DIR/doxygen.config\n\necho \"INPUT = $SOURCE_ROOT\" >> $TEMP_DIR/doxygen.config\necho \"OUTPUT_DIRECTORY = $SYMROOT/RouteMeDoxygen\" >> $TEMP_DIR/doxygen.config\n#echo \"GENERATE_DOCSET = YES\" >> $TEMP_DIR/doxygen.config\n#echo \"DOCSET_BUNDLE_ID = com.mycompany.DoxygenExample\" >> $TEMP_DIR/doxygen.config\n\n# Run doxygen on the updated config file.\n\n$DOXYGEN_PATH $TEMP_DIR/doxygen.config\n\nopen $SYMROOT/RouteMeDoxygen/html/index.html\n\nexit 0\n";
};
2BF307960F8AC60C007014EE /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = $SOURCE_ROOT/RunIPhoneUnitTest.sh;
};
386676E00F6B73DA00C56B17 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
... ... @@ -704,6 +850,57 @@
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
2BF3078C0F8AC5C0007014EE /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
2BEC60170F8AC6B8008FB858 /* GTMIPhoneUnitTestDelegate.m in Sources */,
2BEC60180F8AC6B9008FB858 /* GTMIPhoneUnitTestMain.m in Sources */,
2BEC60190F8AC6BA008FB858 /* GTMSenTestCase.m in Sources */,
2BEC602C0F8AC6FC008FB858 /* FMDatabase.m in Sources */,
2BEC602D0F8AC6FE008FB858 /* FMDatabaseAdditions.m in Sources */,
2BEC602F0F8AC700008FB858 /* FMResultSet.m in Sources */,
2BEC60300F8AC70C008FB858 /* RMAbstractMercatorWebSource.m in Sources */,
2BEC60310F8AC70D008FB858 /* RMCachedTileSource.m in Sources */,
2BEC60320F8AC70E008FB858 /* RMCloudMadeMapSource.m in Sources */,
2BEC60330F8AC70F008FB858 /* RMConfiguration.m in Sources */,
2BEC60340F8AC712008FB858 /* RMCoreAnimationRenderer.m in Sources */,
2BEC60350F8AC713008FB858 /* RMDatabaseCache.m in Sources */,
2BEC60360F8AC715008FB858 /* RMFileTileImage.m in Sources */,
2BEC60370F8AC718008FB858 /* RMFoundation.c in Sources */,
2BEC60380F8AC71A008FB858 /* RMFractalTileProjection.m in Sources */,
2BEC60390F8AC71C008FB858 /* RMGeoHash.m in Sources */,
2BEC603A0F8AC71D008FB858 /* RMLayerSet.m in Sources */,
2BEC603B0F8AC71E008FB858 /* RMMapContents.m in Sources */,
2BEC603C0F8AC71F008FB858 /* RMMapLayer.m in Sources */,
2BEC603D0F8AC722008FB858 /* RMMapRenderer.m in Sources */,
2BEC603E0F8AC723008FB858 /* RMMapView.m in Sources */,
2BEC603F0F8AC724008FB858 /* RMMarker.m in Sources */,
2BEC60400F8AC725008FB858 /* RMMarkerManager.m in Sources */,
2BEC60410F8AC726008FB858 /* RMMarkerStyle.m in Sources */,
2BEC60420F8AC728008FB858 /* RMMarkerStyles.m in Sources */,
2BEC60430F8AC729008FB858 /* RMMemoryCache.m in Sources */,
2BEC60440F8AC729008FB858 /* RMMercatorToScreenProjection.m in Sources */,
2BEC60450F8AC72B008FB858 /* RMOpenAerialMapSource.m in Sources */,
2BEC60460F8AC72C008FB858 /* RMOpenStreetMapsSource.m in Sources */,
2BEC60470F8AC72E008FB858 /* RMPath.m in Sources */,
2BEC60480F8AC72F008FB858 /* RMPixel.c in Sources */,
2BEC60490F8AC738008FB858 /* RMProjection.m in Sources */,
2BEC604A0F8AC739008FB858 /* RMTile.c in Sources */,
2BEC604B0F8AC73A008FB858 /* RMTileCache.m in Sources */,
2BEC604C0F8AC73C008FB858 /* RMTileCacheDAO.m in Sources */,
2BEC604D0F8AC73D008FB858 /* RMTiledLayerController.m in Sources */,
2BEC604E0F8AC73D008FB858 /* RMTileImage.m in Sources */,
2BEC604F0F8AC73E008FB858 /* RMTileImageSet.m in Sources */,
2BEC60500F8AC73F008FB858 /* RMTileLoader.m in Sources */,
2BEC60510F8AC740008FB858 /* RMTileProxy.m in Sources */,
2BEC60520F8AC741008FB858 /* RMTransform.m in Sources */,
2BEC60530F8AC742008FB858 /* RMVirtualEarthSource.m in Sources */,
2BEC60540F8AC744008FB858 /* RMWebTileImage.m in Sources */,
2BEC60550F8AC745008FB858 /* RMYahooMapSource.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
B8C974340E8A19B2007D16AD /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
... ... @@ -754,6 +951,11 @@
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
2BEC606D0F8AC7B3008FB858 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Proj4;
targetProxy = 2BEC606C0F8AC7B3008FB858 /* PBXContainerItemProxy */;
};
B8C974140E8A19B2007D16AD /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
name = Proj4;
... ... @@ -785,6 +987,61 @@
};
name = Release;
};
2BF307920F8AC5C0007014EE /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
COPY_PHASE_STRIP = NO;
GCC_DYNAMIC_NO_PIC = NO;
GCC_ENABLE_SYMBOL_SEPARATION = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = MapView_Prefix.pch;
HEADER_SEARCH_PATHS = ../Proj4;
INFOPLIST_FILE = "RM Unit Tests-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
UIKit,
);
PREBINDING = NO;
PRODUCT_NAME = "RM Unit Tests";
SDKROOT = iphoneos2.1;
};
name = Debug;
};
2BF307930F8AC5C0007014EE /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Don't Code Sign";
COPY_PHASE_STRIP = YES;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_ENABLE_SYMBOL_SEPARATION = YES;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = MapView_Prefix.pch;
HEADER_SEARCH_PATHS = ../Proj4;
INFOPLIST_FILE = "RM Unit Tests-Info.plist";
INSTALL_PATH = "$(HOME)/Applications";
OTHER_LDFLAGS = (
"-framework",
Foundation,
"-framework",
UIKit,
);
PREBINDING = NO;
PRODUCT_NAME = "RM Unit Tests";
SDKROOT = iphoneos2.1;
ZERO_LINK = NO;
};
name = Release;
};
386676D50F6B73AD00C56B17 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
... ... @@ -898,6 +1155,15 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
2BF307940F8AC5C1007014EE /* Build configuration list for PBXNativeTarget "RM Unit Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
2BF307920F8AC5C0007014EE /* Debug */,
2BF307930F8AC5C0007014EE /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Debug;
};
386676DE0F6B73D000C56B17 /* Build configuration list for PBXAggregateTarget "MapView-framework" */ = {
isa = XCConfigurationList;
buildConfigurations = (
... ...
... ... @@ -5,6 +5,7 @@
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreLocation/CLLocation.h>
#endif
... ...
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.yourcompany.${PRODUCT_NAME:identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>NSMainNibFile</key>
<string>MainWindow</string>
</dict>
</plist>
... ...
#!/bin/sh
# RunIPhoneUnitTest.sh
# 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.
#
# Runs all unittests through the 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"
"$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -RegisterForSystemEvents
exit 0
... ...
//
// Prefix header for all source files of the 'MapView' target in the 'MapView' project
//
#ifdef __OBJC__
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <CoreLocation/CLLocation.h>
#endif
#if DEBUG
#define RMLog(args...) NSLog( @"%@", [NSString stringWithFormat: args])
#define LogMethod() NSLog(@"%s logged method call: -[%@ %s] (line %d)", _cmd, self, _cmd, __LINE__)
#define WarnDeprecated() NSLog(@"***** WARNING: %s deprecated method call: -[%@ %s] (line %d)", _cmd, self, _cmd, __LINE__)
#else
// DEBUG not defined:
#define RMLog(args...) // do nothing.
#define LogMethod()
#define WarnDeprecated()
#define NS_BLOCK_ASSERTIONS 1
#endif
... ...