diff --git a/.gitignore b/.gitignore index 8a8ba7b1..3e0201e9 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,3 @@ build *.pbxuser *.mode1v3 .DS_Store -GHUnit diff --git a/Classes/Tests/ASIFormDataRequestTests.h b/Classes/Tests/ASIFormDataRequestTests.h index 86a39f63..467541e2 100644 --- a/Classes/Tests/ASIFormDataRequestTests.h +++ b/Classes/Tests/ASIFormDataRequestTests.h @@ -6,7 +6,11 @@ // Copyright 2008 All-Seeing Interactive. All rights reserved. // -#import "GHUnit.h" +#if TARGET_OS_IPHONE + #import "GHUnit.h" +#else + #import +#endif @interface ASIFormDataRequestTests : GHTestCase { float progress; diff --git a/Classes/Tests/ASIFormDataRequestTests.m b/Classes/Tests/ASIFormDataRequestTests.m index be38f2de..c9363779 100644 --- a/Classes/Tests/ASIFormDataRequestTests.m +++ b/Classes/Tests/ASIFormDataRequestTests.m @@ -13,7 +13,7 @@ @implementation ASIFormDataRequestTests - (void)testPostWithFileUpload { - NSURL *url = [NSURL URLWithString:@"http://asi/ASIHTTPRequest/tests/post"]; + NSURL *url = [NSURL URLWithString:@"http://allseeing-i.com/ASIHTTPRequest/tests/post"]; //Create a 32kb file unsigned int size = 1024*32; diff --git a/Classes/Tests/ASIHTTPRequestTests.h b/Classes/Tests/ASIHTTPRequestTests.h index 4ca7bca4..f926e7fc 100644 --- a/Classes/Tests/ASIHTTPRequestTests.h +++ b/Classes/Tests/ASIHTTPRequestTests.h @@ -6,7 +6,11 @@ // Copyright 2008 All-Seeing Interactive. All rights reserved. // -#import "GHUnit.h" +#if TARGET_OS_IPHONE + #import "GHUnit.h" +#else + #import +#endif @interface ASIHTTPRequestTests : GHTestCase { float progress; diff --git a/Classes/Tests/ASINetworkQueueTests.h b/Classes/Tests/ASINetworkQueueTests.h index 76f73ee4..46a82822 100755 --- a/Classes/Tests/ASINetworkQueueTests.h +++ b/Classes/Tests/ASINetworkQueueTests.h @@ -6,7 +6,11 @@ // Copyright 2008 All-Seeing Interactive. All rights reserved. // -#import "GHUnit.h" +#if TARGET_OS_IPHONE + #import "GHUnit.h" +#else + #import +#endif @class ASIHTTPRequest; @class ASINetworkQueue; diff --git a/Classes/Tests/GHUnitTestMain.m b/Classes/Tests/GHUnitTestMain.m new file mode 100644 index 00000000..33e9eaf2 --- /dev/null +++ b/Classes/Tests/GHUnitTestMain.m @@ -0,0 +1,66 @@ +// +// GHUnitTestMain.m +// GHUnit +// +// Created by Gabriel Handford on 2/22/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import +#import + +#import +#import +#import + +int main(int argc, char *argv[]) { + // Setup any NSDebug settings + NSDebugEnabled = YES; + NSZombieEnabled = YES; + NSDeallocateZombies = NO; + NSHangOnUncaughtException = YES; + setenv("NSAutoreleaseFreedObjectCheckEnabled", "1", 1); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + // Register any special test case classes + //[[GHTesting sharedInstance] registerClassName:@"GHSpecialTestCase"]; + + int retVal = 0; + // If GHUNIT_CLI is set we are using the command line interface and run the tests + // Otherwise load the GUI app + if (getenv("GHUNIT_CLI")) { + retVal = [GHTestRunner run]; + } else { + // To run all tests (from ENV) + GHTestApp *app = [[GHTestApp alloc] init]; + // To run a different test suite: + //GHTestSuite *suite = [GHTestSuite suiteWithTestFilter:@"GHSlowTest,GHAsyncTestCaseTest"]; + //GHTestApp *app = [[GHTestApp alloc] initWithSuite:suite]; + [NSApp run]; + [app release]; + } + [pool release]; + return retVal; +} diff --git a/Frameworks/GHUnit.framework/GHUnit b/Frameworks/GHUnit.framework/GHUnit new file mode 120000 index 00000000..8ee4e6ce --- /dev/null +++ b/Frameworks/GHUnit.framework/GHUnit @@ -0,0 +1 @@ +Versions/Current/GHUnit \ No newline at end of file diff --git a/Frameworks/GHUnit.framework/Headers b/Frameworks/GHUnit.framework/Headers new file mode 120000 index 00000000..a177d2a6 --- /dev/null +++ b/Frameworks/GHUnit.framework/Headers @@ -0,0 +1 @@ +Versions/Current/Headers \ No newline at end of file diff --git a/Frameworks/GHUnit.framework/Resources b/Frameworks/GHUnit.framework/Resources new file mode 120000 index 00000000..953ee36f --- /dev/null +++ b/Frameworks/GHUnit.framework/Resources @@ -0,0 +1 @@ +Versions/Current/Resources \ No newline at end of file diff --git a/Frameworks/GHUnit.framework/Versions/A/GHUnit b/Frameworks/GHUnit.framework/Versions/A/GHUnit new file mode 100755 index 00000000..e6774e46 Binary files /dev/null and b/Frameworks/GHUnit.framework/Versions/A/GHUnit differ diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHAsyncTestCase.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHAsyncTestCase.h new file mode 100644 index 00000000..c675523c --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHAsyncTestCase.h @@ -0,0 +1,123 @@ +// +// GHAsyncTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 4/8/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestCase.h" + +// Some default statuses to use; Or define and use your own +enum { + kGHUnitWaitStatusUnknown = 0, + kGHUnitWaitStatusSuccess, + kGHUnitWaitStatusFailure, + kGHUnitWaitStatusCancelled +}; + +/*! + Asynchronous test case with wait and notify. + + Handles the case of notify occuring before wait has started (if it was a synchronous call). + Be sure to call prepare before the asynchronous method (otherwise an exception will raise). + + @code + - (void)testSuccess { + [self prepare]; + + // Do asynchronous task here + [self performSelector:@selector(_succeed) withObject:nil afterDelay:0.1]; + + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + + - (void)_succeed { + // Notice the forSelector points to the test above. This is so that + // stray notifies don't error or falsely succeed other tests. + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testSuccess)]; + } + @endcode + */ +@interface GHAsyncTestCase : GHTestCase { + + NSInteger waitForStatus_; + NSInteger notifiedStatus_; + + BOOL prepared_; // Whether prepared was called before waitFor:timeout: + NSRecursiveLock *lock_; // Lock to synchronize on + SEL waitSelector_; // The selector we are waiting on + + NSArray *_runLoopModes; // Run loop modes to run while waiting; Defaults to NSDefaultRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode +} + +@property (retain, nonatomic) NSArray *runLoopModes; + +/*! + Prepare before calling the asynchronous method. + */ +- (void)prepare; + +/*! + Prepare and specify the selector we will use in notify. + + @param selector + */ +- (void)prepare:(SEL)selector; + +/*! + Wait for notification of status or timeout. + + Be sure to prepare before calling your asynchronous method. + For example, + + @code + - (void)testFoo { + [self prepare]; + // Do asynchronous task here + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + @endcode + + @param status kGHUnitWaitStatusSuccess, kGHUnitWaitStatusFailure or custom status + @param timeout Timeout in seconds + */ +- (void)waitFor:(NSInteger)status timeout:(NSTimeInterval)timeout; + +/*! + Wait for timeout to occur. + Fails if we did _NOT_ timeout. + @param timeout + */ +- (void)waitForTimeout:(NSTimeInterval)timeout; + +/*! + Notify of status for test selector. + @param status For example, kGHUnitWaitStatusSuccess + @param selector If not NULL, then will verify this selector is where we are waiting. + This prevents stray asynchronous callbacks to fail a later test + */ +- (void)notify:(NSInteger)status forSelector:(SEL)selector; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSHTTPURLResponse.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSHTTPURLResponse.h new file mode 100644 index 00000000..d0b1aad9 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSHTTPURLResponse.h @@ -0,0 +1,46 @@ +// +// GHMockNSHTTPURLResponse.h +// GHUnit +// +// Created by Gabriel Handford on 4/9/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +/*! + NSHTTPURLResponse for use with mocking. + Allows us to manually set the status code and headers in the response. + */ +@interface GHMockNSHTTPURLResponse : NSHTTPURLResponse { + NSInteger statusCode_; + NSDictionary *headers_; +} + +- (id)initWithStatusCode:(NSInteger)statusCode headers:(NSDictionary *)headers; + +- (void)setStatusCode:(NSInteger)code; +- (void)setHeaders:(NSDictionary *)headers; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSURLConnection.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSURLConnection.h new file mode 100644 index 00000000..0b511abe --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHMockNSURLConnection.h @@ -0,0 +1,143 @@ +// +// GHMockNSURLConnection.h +// GHUnit +// +// Created by Gabriel Handford on 4/9/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +extern NSString *const GHMockNSURLConnectionException; + +/*! + NSURLConnection for mocking. + + Use with GHAsyncTestCase to mock out connections. + + @code + + @interface GHNSURLConnectionMockTest : GHAsyncTestCase {} + @end + + @implementation GHNSURLConnectionMockTest + + - (void)testMock { + [self prepare]; + GHMockNSURLConnection *connection = [[GHMockNSURLConnection alloc] initWithRequest:nil delegate:self]; + [connection receiveHTTPResponseWithStatusCode:204 headers:testHeaders_ afterDelay:0.1]; + [connection receiveData:testData_ afterDelay:0.2]; + [connection finishAfterDelay:0.3]; + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + + - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + GHAssertEquals([(NSHTTPURLResponse *)response statusCode], 204, nil); + GHAssertEqualObjects([(NSHTTPURLResponse *)response allHeaderFields], testHeaders_, nil); + } + + - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + GHAssertEqualObjects(data, testData_, nil); + } + + - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testMock)]; + } + @end + + @endcode + */ +@interface GHMockNSURLConnection : NSObject { + NSURLRequest *request_; + id delegate_; // weak + + BOOL cancelled_; + BOOL started_; +} + +@property (readonly, nonatomic, getter=isStarted) BOOL started; +@property (readonly, nonatomic, getter=isCancelled) BOOL cancelled; + +// Mocked version of NSURLConnection#initWithRequest:delegate: +- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate; + +// Mocked version of NSURLConnection#initWithRequest:delegate:startImmediately: +- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately; + +// Mocked version of NSURLConnection#scheduleInRunLoop:forMode: (NOOP) +- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; + +// Mocked version of NSURLConnection#start (NOOP) +- (void)start; + +/*! + Send generic response to delegate after delay. + (For asynchronous requests) + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)receiveResponse:(NSURLResponse *)response afterDelay:(NSTimeInterval)delay; + +/*! + Send HTTP response to delegate with status code, headers, after delay. + This is only the HTTP response (and not data or finished). + (For asynchronous requests) + @param statusCode HTTP status code + @param headers Headers + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)receiveHTTPResponseWithStatusCode:(int)statusCode headers:(NSDictionary *)headers afterDelay:(NSTimeInterval)delay; + +/*! + Send data to connection delegate after delay. + @param data Data to send + @param delay Delay in seconds + */ +- (void)receiveData:(NSData *)data afterDelay:(NSTimeInterval)delay; + +/*! + Send data (from file in bundle resource) to connection delegate after delay. + (For asynchronous requests) + @param path Path to file + @param delay Delay in seconds + */ +- (void)receiveDataFromPath:(NSString *)path afterDelay:(NSTimeInterval)delay; + +/*! + Calls connectionDidFinish: delegate after delay. + (For asynchronous requests) + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)finishAfterDelay:(NSTimeInterval)delay; + +/*! + Sends mock response, sends data, and then calls finish. + (For asynchronous requests) + @param path Data to load path from. File should be available in Test target (bundle) + @param statusCode Status code for response + @param MIMEType Content type for response header + @param afterDelay Delay before responding (if < 0, there is no delay) + */ +- (void)receiveFromPath:(NSString *)path statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType afterDelay:(NSTimeInterval)delay; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSLocale+Mock.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSLocale+Mock.h new file mode 100644 index 00000000..41cc02a0 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSLocale+Mock.h @@ -0,0 +1,59 @@ +// +// GHMockNSLocale.h +// GHUnitIPhone +// +// Created by Gabriel Handford on 4/13/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +/*! + Category for overriding the current locale at runtime. + + @code + #import "GHNSLocale+Mock.h" + // This aliases the currentLocale method and with the specified locale identifier + [NSLocale gh_setLocaleIdentifier:@"en_GB"]; + + [[NSLocale currentLocale] localeIdentifier] == "en_GB" + @endcode + */ +@interface NSLocale (GHMock) + ++ (void)gh_setLocaleIdentifier:(NSString *)localeIdentifier; + +/*! + Aliases to currentLocale with locale set from gh_setLocaleIdentifier. + If not set, defaults to NSLocale with identifier en_US. + */ ++ (NSLocale *)gh_currentLocale; + ++ (void)gh_setPreferredLanguages:(NSArray *)preferredLanguages; + +/*! + Aliases to preferredLanguages set from gh_setPreferredLanguages. + If not set, defaults to [@"en"]. + */ ++ (NSArray *)gh_preferredLanguages; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSObject+Invocation.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSObject+Invocation.h new file mode 100644 index 00000000..25cfac6e --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHNSObject+Invocation.h @@ -0,0 +1,86 @@ +// +// GHNSObject+Invocation.h +// GHKit +// +// Created by Gabriel Handford on 1/18/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHNSInvocation+Utils.h" + +/*! + Adds performSelector methods that take a nil-terminated variable argument list, + for when you need to pass more arguments to performSelector. + */ +@interface NSObject (GHInvocation_GHUNIT) + +/*! + Perform selector if responds. + @param selector + @result nil if we don't respond to the selector, otherwise the selector result + */ +- (id)ghu_performIfRespondsToSelector:(SEL)selector; + +/*! + Perform selector if responds with multiple arguments. + @param selector + @param withObjects nil terminated variable argument list + @result nil if we don't respond to the selector, otherwise the selector result + */ +- (id)ghu_performIfRespondsToSelector:(SEL)selector withObjects:object, ...; + +/*! + Invoke selector with arguments. + @param selector + @param withObjects nil terminated variable argument list + */ +- (id)ghu_performSelector:(SEL)selector withObjects:object, ...; + +- (id)ghu_performSelector:(SEL)selector afterDelay:(NSTimeInterval)delay withObjects:object, ...; + +/*! + Invoke selector with arguments on main thread. + Does not wait until selector is finished. + @param selector + @param withObjects nil terminated variable argument list + */ +- (void)ghu_performSelectorOnMainThread:(SEL)selector withObjects:object, ...; + +/*! + Invoke selector with arguments on main thread. + @param selector + @param waitUntilDone Whether to join on selector and wait for it to finish. + @param withObjects nil terminated variable argument list + */ +- (void)ghu_performSelectorOnMainThread:(SEL)selector waitUntilDone:(BOOL)waitUntilDone withObjects:object, ...; + + +- (void)ghu_performSelector:(SEL)selector onMainThread:(BOOL)onMainThread waitUntilDone:(BOOL)waitUntilDone withObjects:object, ...; + +- (void)ghu_performSelector:(SEL)selector onMainThread:(BOOL)onMainThread waitUntilDone:(BOOL)waitUntilDone arguments:(NSArray *)arguments; + +- (void)ghu_performSelector:(SEL)selector onMainThread:(BOOL)onMainThread waitUntilDone:(BOOL)waitUntilDone + afterDelay:(NSTimeInterval)delay arguments:(NSArray *)arguments; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTest.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTest.h new file mode 100644 index 00000000..d1535f57 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTest.h @@ -0,0 +1,171 @@ +// +// GHTest.h +// GHKit +// +// Created by Gabriel Handford on 1/18/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +/*! + Test status. + */ +typedef enum { + GHTestStatusNone = 0, + GHTestStatusRunning, + GHTestStatusFinished, + GHTestStatusIgnored +} GHTestStatus; + +/*! + Generate string from GHTestStatus + @param status + */ +NSString* NSStringFromGHTestStatus(GHTestStatus status); + +/*! + Test stats. + */ +typedef struct { + NSInteger runCount; + NSInteger failureCount; + NSInteger ignoreCount; + NSInteger testCount; +} GHTestStats; + +/*! + Create GHTestStats. + */ +GHTestStats GHTestStatsMake(NSInteger runCount, NSInteger failureCount, NSInteger ignoreCount, NSInteger testCount); + +#define NSStringFromGHTestStats(stats) [NSString stringWithFormat:@"%d/%d/%d", stats.runCount, stats.testCount, stats.failureCount] + +@protocol GHTestDelegate; + +/*! + The base interface for a runnable test. + A runnable with a unique identifier, display name, stats, timer, delegate, log and error handling. + */ +@protocol GHTest + +- (void)run; + +- (NSString *)identifier; +- (NSString *)name; + +- (NSTimeInterval)interval; +- (GHTestStatus)status; +- (GHTestStats)stats; + +- (void)setDelegate:(id)delegate; + +- (NSException *)exception; + +- (NSArray *)log; + +- (BOOL)ignore; +- (void)setIgnore:(BOOL)ignore; + +@end + +/*! + Test delegate for notification when a test starts and ends. + */ +@protocol GHTestDelegate +- (void)testDidStart:(id)test; +- (void)testDidFinish:(id)test; +- (void)test:(id)test didLog:(NSString *)message; +- (void)testDidIgnore:(id)test; +@end + +/*! + Delegate which is notified of log messages from inside GHTestCase. + */ +@protocol GHTestCaseLogDelegate +- (void)testCase:(id)testCase didLog:(NSString *)message; +@end + +/*! + Default test implementation target with a target/selector pair. + - Consists of a target/selector + - Notifies a test delegate + - Keeps track of status, running time and failures + - Stores any test specific logging + */ +@interface GHTest : NSObject { + + id delegate_; // weak + + id target_; + SEL selector_; + + NSString *identifier_; + NSString *name_; + GHTestStatus status_; + NSTimeInterval interval_; + BOOL failed_; + NSException *exception_; // If failed + + GHTestStats stats_; + + NSMutableArray *log_; + + BOOL ignore_; +} + +/*! + Create test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ +- (id)initWithTarget:(id)target selector:(SEL)selector; + +/*! + Create autoreleased test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ ++ (id)testWithTarget:(id)target selector:(SEL)selector; + +@property (readonly, nonatomic) id target; +@property (readonly, nonatomic) SEL selector; +@property (readonly, nonatomic) NSString *identifier; // Unique identifier for test +@property (readonly, nonatomic) NSString *name; +@property (readonly, nonatomic) NSTimeInterval interval; +@property (readonly, nonatomic) NSException *exception; +@property (readonly, nonatomic) GHTestStatus status; +@property (readonly, nonatomic) BOOL failed; +@property (readonly, nonatomic) GHTestStats stats; +@property (readonly, nonatomic) NSArray *log; + +@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) BOOL ignore; + +/*! + Run the test. + After running, the interval and exception properties may be set. + @result YES if passed, NO otherwise + */ +- (void)run; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestApp.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestApp.h new file mode 100644 index 00000000..4caa87b6 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestApp.h @@ -0,0 +1,25 @@ +// +// GHTestApp.h +// GHUnit +// +// Created by Gabriel Handford on 1/20/09. +// Copyright 2009. All rights reserved. +// + +#import "GHTestWindowController.h" + +#import "GHTestRunner.h" + +@interface GHTestApp : NSObject { + NSMutableArray *topLevelObjects_; + + GHTestWindowController *windowController_; + + GHTestSuite *suite_; +} + +- (id)initWithSuite:(GHTestSuite *)suite; + +- (void)runTests; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestCase.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestCase.h new file mode 100644 index 00000000..9472a494 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestCase.h @@ -0,0 +1,133 @@ +// +// GHTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 1/21/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTestMacros.h" +#import "GHTest.h" + +// Log to your test case logger. +// For example, GHTestLog(@"Some debug info, %@", obj) +#define GHTestLog(...) [self log:[NSString stringWithFormat:__VA_ARGS__, nil]] + +/*! + @brief The base class for a test case. + + @code + @interface MyTest : GHTestCase {} + @end + + @implementation MyTest + + // Run before each test method + - (void)setUp { } + + // Run after each test method + - (void)tearDown { } + + // Run before the tests are run for this class + - (void)setUpClass { } + + // Run before the tests are run for this class + - (void)tearDownClass { } + + // Tests are prefixed by 'test' and contain no arguments and no return value + - (void)testA { + GHTestLog(@"Log with a test with the GHTestLog(...) for test specific logging."); + } + + // Another test; Tests are run in lexical order + - (void)testB { } + + // Override any exceptions; By default exceptions are raised, causing a test failure + - (void)failWithException:(NSException*)exception { } + + @end + @endcode + + */ +@interface GHTestCase : NSObject { + id logDelegate_; // weak + + SEL currentSelector_; +} + +//! The current test selector +@property (assign, nonatomic) SEL currentSelector; +@property (assign, nonatomic) id logDelegate; + +// GTM_BEGIN +//! Run before each test method +- (void)setUp; + +//! Run after each test method +- (void)tearDown; + +/*! + By default exceptions are raised, causing a test failure + @brief Override any exceptions + @param exception Exception that was raised by test + */ +- (void)failWithException:(NSException*)exception; +// GTM_END + +//! Run before the tests (once per test case) +- (void)setUpClass; + +//! Run after the tests (once per test case) +- (void)tearDownClass; + +//! Any special handling of exceptions after they are thrown; By default logs stack trace to standard out. +- (void)handleException:(NSException *)exception; + +/*! + Log a message, which notifies the log delegate. + This is not meant to be used directly, see GHTestLog(...) macro. + @param message + */ +- (void)log:(NSString *)message; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestGroup.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestGroup.h new file mode 100644 index 00000000..25783585 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestGroup.h @@ -0,0 +1,164 @@ +// +// GHTestGroup.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTest.h" +#import "GHTestCase.h" + +/*! + @brief Interface for a group of tests. + + This group conforms to the GHTest protocol as well (see Composite pattern). + */ +@protocol GHTestGroup +- (NSString *)name; +- (id)parent; +- (NSArray *)children; +@end + +/*! + @brief A collection of tests (or test groups). + + A test group is a collection of id, that may represent a set of test case methods. + + For example, if you had the following GHTestCase. + + @code + @interface FooTest : GHTestCase {} + - (void)testFoo; + - (void)testBar; + @end + @endcode + + The GHTestGroup would consist of and array of GHTest, [FooTest#testFoo and FooTest#testBar], + each test being a target and selector pair. + + A test group may also consist of a group of groups (since GHTestGroup conforms to GHTest), + and this might represent a GHTestSuite. + */ +@interface GHTestGroup : NSObject { + + id delegate_; // weak + id parent_; // weak + + NSMutableArray *children_; // of id + + NSString *name_; // The name of the test group (usually the class name of the test case + NSTimeInterval interval_; // Total time of child tests + GHTestStatus status_; // Current status of the group (current status of running or completed child tests) + GHTestStats stats_; // Current stats for the group (aggregate of child test stats) + + id testCase_; // Is set if test is created from initWithTestCase:delegate: + id currentTest_; // weak + + NSException *exception_; // If exception happens in group setUpClass/tearDownClass + + BOOL ignore_; +} + +@property (readonly, nonatomic) NSArray *children; +@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) id parent; +@property (readonly, nonatomic) id testCase; + +@property (readonly, nonatomic) NSString *identifier; +@property (readonly, nonatomic) NSString *name; +@property (readonly, nonatomic) GHTestStatus status; + +@property (readonly, nonatomic) NSTimeInterval interval; +@property (readonly, nonatomic) GHTestStats stats; + +@property (assign, nonatomic) BOOL ignore; + +/*! + Create an empty test group. + @param name The name of the test group + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithName:(NSString *)name delegate:(id)delegate; + +/*! + Create test group from a test case. + + A test group is a collection of GHTest. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithTestCase:(id)testCase delegate:(id)delegate; + +/*! + Create test group from a single test. + @param testCase + @param selector Test to run + @param delegate + */ +- (id)initWithTestCase:(id)testCase selector:(SEL)selector delegate:(id)delegate; + +/*! + Create test group from a test case. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ ++ (GHTestGroup *)testGroupFromTestCase:(id)testCase delegate:(id)delegate; + +/*! + Add a test case (or test group) to this test group. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + */ +- (void)addTestCase:(id)testCase; + +- (void)addTestGroup:(GHTestGroup *)testGroup; + +/*! + Run the test group. + Will notify delegate as tests are run. + */ +- (void)run; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestMacros.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestMacros.h new file mode 100644 index 00000000..b8080d1f --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestMacros.h @@ -0,0 +1,1004 @@ +// +// GHTestMacros.h +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// 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. + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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. +// + +// GTM_BEGIN + +extern NSString *const GHTestFilenameKey; +extern NSString *const GHTestLineNumberKey; +extern NSString *const GHTestFailureException; + +NSString *GHComposeString(NSString *, ...); + +// 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 GHAssertNoErr(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, GHComposeString(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:GHComposeString(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 GHAssertErr(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, GHComposeString(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) fails", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +// Generates a failure when a1 is NULL +// Args: +// a1: should be a pointer (use GHAssertNotNil 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 GHAssertNotNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value == NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) != NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when a1 is not NULL +// Args: +// a1: should be a pointer (use GHAssertNil 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 GHAssertNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value != NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) == NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when a1 is equal 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 GHAssertNotEquals(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:GHComposeString(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, GHComposeString(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:GHComposeString(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 GHAssertNotEqualObjects(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, GHComposeString(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:GHComposeString(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 GHAssertOperation(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:GHComposeString(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, GHComposeString(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:GHComposeString(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 GHAssertGreaterThan(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertGreaterThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertLessThan(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertLessThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, <=, description, ##__VA_ARGS__) + +// Generates a failure when string a1 is not equal to string a2. This call +// differs from GHAssertEqualObjects 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 GHAssertEqualStrings(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when string a1 is equal to string a2. This call +// differs from GHAssertEqualObjects 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 GHAssertNotEqualStrings(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: GHComposeString(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:GHComposeString(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 GHAssertEqualCStrings(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: GHComposeString(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:GHComposeString(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 GHAssertNotEqualCStrings(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// GTM_END + +// 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 GHAssertEqualObjects(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: GHComposeString(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:GHComposeString(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 GHAssertEquals(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:GHComposeString(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +#define GHAbsoluteDifference(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 GHAssertEqualsWithAccuracy(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:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +__typeof__(accuracy) accuracyvalue = (accuracy); \ +if (GHAbsoluteDifference(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: GHComposeString(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:GHComposeString(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 GHFail(description, ...) \ +[self failWithException:[NSException failureInFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(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 GHAssertNil(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: GHComposeString(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:GHComposeString(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 GHAssertNotNil(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: GHComposeString(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:GHComposeString(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 GHAssertTrue(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: GHComposeString(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 GHAssertTrueNoThrow(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: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(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 GHAssertFalse(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: GHComposeString(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 GHAssertFalseNoThrow(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: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"!(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(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 GHAssertThrows(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: GHComposeString(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 GHAssertThrowsSpecific(expr, specificException, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_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 GHAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) continue; \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_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 GHAssertNoThrow(expr, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (id anException) { \ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(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 GHAssertNoThrowSpecific(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: GHComposeString(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 GHAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) { \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +} \ +continue; \ +}\ +@catch (id anythingElse) {\ +; \ +}\ +} while (0) + + +@interface NSException (GHTestMacros_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 diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestRunner.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestRunner.h new file mode 100644 index 00000000..132e9e8f --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestRunner.h @@ -0,0 +1,131 @@ +// +// GHTestRunner.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2008 Gabriel Handford +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTestGroup.h" +#import "GHTestSuite.h" + +@class GHTestRunner; + +// Delegates can be guaranteed to be notified on the main thread (using #delegateOnMainThread) +@protocol GHTestRunnerDelegate +@optional +- (void)testRunnerDidStart:(GHTestRunner *)runner; +- (void)testRunner:(GHTestRunner *)runner didStartTest:(id)test; +- (void)testRunner:(GHTestRunner *)runner didFinishTest:(id)test; +- (void)testRunnerDidFinish:(GHTestRunner *)runner; + +- (void)testRunner:(GHTestRunner *)runner didLog:(NSString *)message; +- (void)testRunner:(GHTestRunner *)runner test:(id)test didLog:(NSString *)message; +@end + +/*! + Runs the tests. + Tests are run a separate thread though delegates are called on the + main thread by default (see #delegateOnMainThread). + */ +@interface GHTestRunner : NSObject { + + id test_; // The test to run; Could be a GHTestGroup (suite), GHTestGroup (test case), or GHTest (target/selector) + + id delegate_; // weak + + // If YES, will allow exceptions to be raised (so you can trigger the debugger) + BOOL raiseExceptions_; + + // If yes, delegate calls will occur on the main thread + // Defaults to YES. + BOOL delegateOnMainThread_; + +} + +@property (retain) id test; +@property (assign) id delegate; +@property (assign) BOOL raiseExceptions; +@property (assign) BOOL delegateOnMainThread; +@property (readonly) GHTestStats stats; + +/*! + Create runner for test. + @param test + */ +- (id)initWithTest:(id)test; + +/*! + Create runner for all tests. + @see GHTesting#loadAllTestCases. + @result Runner + */ ++ (GHTestRunner *)runnerForAllTests; + +/*! + Create runner for test suite. + @param suite + @result Runner + */ ++ (GHTestRunner *)runnerForSuite:(GHTestSuite *)suite; + +/*! + Get the runner from the environment. + If the TEST env is set, then we will only run that test case or test method. + */ ++ (GHTestRunner *)runnerFromEnv; + +/*! + Run the test runner. Usually called from the test main. + Reads the TEST environment variable and filters on that; or all tests are run. + @result Return value, 0 is success, otherwise the failure count + */ ++ (int)run; + +/*! + Start the test runner. + */ +- (void)run; + +@end + + diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestSuite.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestSuite.h new file mode 100644 index 00000000..e80ef32a --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestSuite.h @@ -0,0 +1,88 @@ +// +// GHTestSuite.h +// GHUnit +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestGroup.h" + +/*! + Test suite is an alias for test group. + + A test case is an instance of a test case class with test methods. + A test is a id which represents a target and a selector. + A test group is a collection of tests; A collection of id (GHTest or GHTestGroup). + + For example, if you have 2 test cases, GHTestCase1 (with some test methods) and GHTestCase2 (with some test methods), + your test suite might look like: + +"Tests" (GHTestSuite) + GHTestGroup (collection of tests from GHTestCase1) + - (void)testA1 (GHTest with target GHTestCase1 + testA1) + - (void)testA2 (GHTest with target GHTestCase1 + testA2) + GHTestGroup (collection of tests from GHTestCase2) + - (void)testB1; (GHTest with target GHTestCase2 + testB1) + - (void)testB2; (GHTest with target GHTestCase2 + testB2) + + */ +@interface GHTestSuite : GHTestGroup { + +} + +/*! + Create test suite with test cases. + @param name Label to give the suite + @param testCases Array of init'ed test case classes + @param delegate + */ +- (id)initWithName:(NSString *)name testCases:(NSArray *)testCases delegate:(id)delegate; + +/*! + Creates a suite of all tests. + Will load all classes that subclass from GHTestCase, SenTestCase or GTMTestCase (or register test case class). + */ ++ (GHTestSuite *)allTests; + +/*! + Create suite of tests with filter. + This is useful for running a single test or all tests in a single test case. + + For example, + 'GHSlowTest' -- Runs all test method in GHSlowTest + 'GHSlowTest/testSlowA -- Only runs the test method testSlowA in GHSlowTest + + @param testFilter Test filter + @result Suite + */ ++ (GHTestSuite *)suiteWithTestFilter:(NSString *)testFilter; + +/*! + Return test suite based on environment (TEST=TestFoo/foo) + @result Suite + */ ++ (GHTestSuite *)suiteFromEnv; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewController.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewController.h new file mode 100644 index 00000000..545abc1b --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewController.h @@ -0,0 +1,78 @@ +// +// GHTestViewController.h +// GHKit +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestViewModel.h" +#import "GHTestGroup.h" + +@interface GHTestViewController : NSViewController { + NSSplitView *splitView_; + NSView *statusView_; + NSView *detailsView_; + + NSTextField *statusLabel_; + NSProgressIndicator *progressIndicator_; + NSOutlineView *outlineView_; + + NSSegmentedControl *textSegmentedControl_; + NSTextView *textView_; + + BOOL wrapInTextView_; + + GHTestViewModel *model_; +} + +// Assign since they are retained as subviews +@property (assign, nonatomic) IBOutlet NSSplitView *splitView; +@property (assign, nonatomic) IBOutlet NSView *statusView; +@property (assign, nonatomic) IBOutlet NSView *detailsView; +@property (assign, nonatomic) IBOutlet NSTextField *statusLabel; +@property (assign, nonatomic) IBOutlet NSProgressIndicator *progressIndicator; +@property (assign, nonatomic) IBOutlet NSOutlineView *outlineView; +@property (assign, nonatomic) IBOutlet NSSegmentedControl *textSegmentedControl; +@property (assign, nonatomic) IBOutlet NSTextView *textView; +@property (assign, nonatomic) BOOL wrapInTextView; +@property (readonly, nonatomic) id selectedTest; + +@property (copy, nonatomic) NSString *status; + +- (void)log:(NSString *)log; +- (void)test:(id)test didLog:(NSString *)message; + +- (void)updateTest:(id)test; + +- (void)setRoot:(id)root; + +- (void)selectFirstFailure; + +- (GHTestNode *)findFailure; +- (GHTestNode *)findFailureFromNode:(GHTestNode *)node; + +- (IBAction)copy:(id)sender; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewModel.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewModel.h new file mode 100644 index 00000000..6757436a --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestViewModel.h @@ -0,0 +1,125 @@ +// +// GHTest.h +// GHKit +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestGroup.h" + +@class GHTestNode; + +@protocol GHTestNodeDelegate +- (void)testNodeDidChange:(GHTestNode *)node; +@end + + +/*! + Test view model for use in a tree view. + */ +@interface GHTestViewModel : NSObject { + + GHTestNode *root_; + + NSMutableDictionary *map_; // id#identifier -> GHTestNode + + NSString *settingsKey_; + NSMutableDictionary *settings_; +} + +@property (readonly, nonatomic) GHTestNode *root; + +/*! + Create view model with root test group node. + */ +- (id)initWithRoot:(id)root; + +- (NSString *)name; +- (NSString *)statusString; + +/*! + Get the test node from the test. + @param test + */ +- (GHTestNode *)findTestNode:(id)test; + +/*! + Register node, so that we can do a lookup later (see #findTestNode). + @param node + */ +- (void)registerNode:(GHTestNode *)node; + +// Return number of test groups +- (NSInteger)numberOfGroups; + +// Return number of tests in group +- (NSInteger)numberOfTestsInGroup:(NSInteger)group; + +/*! + Search for path to test. + @param test + @result Index path + */ +- (NSIndexPath *)indexPathToTest:(id)test; + +@end + + +@interface GHTestNode : NSObject { + + id test_; // The test + NSMutableArray *children_; // of GHTestNode + + id delegate_; +} + + + +@property (readonly, nonatomic) NSString *identifier; +@property (readonly, nonatomic) NSString *name; +@property (readonly, nonatomic) NSArray *children; // of GHTestNode +@property (readonly, nonatomic) id test; +@property (readonly, nonatomic) GHTestStatus status; +@property (readonly, nonatomic) BOOL failed; +@property (readonly, nonatomic) NSString *statusString; +@property (readonly, nonatomic) NSString *stackTrace; +@property (readonly, nonatomic) NSString *log; +@property (readonly, nonatomic) BOOL isRunning; +@property (readonly, nonatomic) BOOL isFinished; +@property (readonly, nonatomic) BOOL isGroupTest; // YES if test has "sub tests" + +@property (assign, nonatomic, getter=isSelected) BOOL selected; +@property (assign, nonatomic) id delegate; + +- (id)initWithTest:(id)test children:(NSArray */*of GHTestNode */)children source:(GHTestViewModel *)source; ++ (GHTestNode *)nodeWithTest:(id)test children:(NSArray */*of GHTestNode */)children source:(GHTestViewModel *)source; + +- (NSString *)nameWithStatus; + +- (BOOL)hasChildren; + +- (void)notifyChanged; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestWindowController.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestWindowController.h new file mode 100644 index 00000000..1df7ea3b --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTestWindowController.h @@ -0,0 +1,38 @@ +// +// GHTestWindowController.h +// GHKit +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestViewController.h" + +@interface GHTestWindowController : NSWindowController { + GHTestViewController *viewController_; +} + +@property (retain, nonatomic) IBOutlet GHTestViewController *viewController; + +@end diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHTesting.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTesting.h new file mode 100644 index 00000000..16ddc3b0 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHTesting.h @@ -0,0 +1,104 @@ +// +// GHTesting.h +// GHUnit +// +// Created by Gabriel Handford on 1/30/09. +// Copyright 2008 Gabriel Handford +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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. +// + +// GTM_BEGIN +BOOL isTestFixtureOfClass(Class aClass, Class testCaseClass); +// GTM_END + +/*! + Utility test for loading and running tests. + @note Much of this is borrowed from GTM/UnitTesting. + */ +@interface GHTesting : NSObject { + + NSMutableArray/* of NSString*/ *testCaseClassNames_; + +} + +/*! + The shared testing instance. + */ ++ (GHTesting *)sharedInstance; + +/*! + Load all test classes that we can "see". + @return Array of initialized (and autoreleased) test case classes in an autoreleased array. + */ +- (NSArray *)loadAllTestCases; + +/*! + Load tests from target. + @result Array of id + */ +- (NSArray *)loadTestsFromTarget:(id)target; + +/*! + See if class is of a registered test case class. + */ +- (BOOL)isTestCaseClass:(Class)aClass; + +/*! + Register test case class. + @param aClass + */ +- (void)registerClass:(Class)aClass; + +/*! + Register test case class by name. + @param className Class name (via NSStringFromClass(aClass) + */ +- (void)registerClassName:(NSString *)className; + +/*! + Run test. + Exception if set is retained and should be released by the caller. + */ +- (BOOL)runTest:(id)target selector:(SEL)selector exception:(NSException **)exception interval:(NSTimeInterval *)interval; + +@end + diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHUNSObject+Swizzle.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHUNSObject+Swizzle.h new file mode 100644 index 00000000..77d9a197 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHUNSObject+Swizzle.h @@ -0,0 +1,36 @@ +// +// GHNSObject+Swizzle.h +// GHUnit +// +// Created by Gabriel Handford on 4/13/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +@interface NSObject (GHUSwizzle) + ++ (void)ghu_swizzleMethod:(SEL)original withMethod:(SEL)alternate; ++ (void)ghu_swizzleClassMethod:(SEL)original withClassMethod:(SEL)alternate; + +@end + diff --git a/Frameworks/GHUnit.framework/Versions/A/Headers/GHUnit.h b/Frameworks/GHUnit.framework/Versions/A/Headers/GHUnit.h new file mode 100644 index 00000000..1501d04b --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Headers/GHUnit.h @@ -0,0 +1,34 @@ +// +// GHUnit.h +// GHUnit +// +// Created by Gabriel Handford on 1/19/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestCase.h" +#import "GHAsyncTestCase.h" +#import "GHTestSuite.h" +#import "GHTestMacros.h" +#import "GHTestRunner.h" diff --git a/Frameworks/GHUnit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings b/Frameworks/GHUnit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings new file mode 100644 index 00000000..dea12de4 Binary files /dev/null and b/Frameworks/GHUnit.framework/Versions/A/Resources/English.lproj/InfoPlist.strings differ diff --git a/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestApp.nib b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestApp.nib new file mode 100644 index 00000000..aa93464e Binary files /dev/null and b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestApp.nib differ diff --git a/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestView.nib b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestView.nib new file mode 100644 index 00000000..2453ef7c Binary files /dev/null and b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestView.nib differ diff --git a/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestWindow.nib b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestWindow.nib new file mode 100644 index 00000000..c27387eb Binary files /dev/null and b/Frameworks/GHUnit.framework/Versions/A/Resources/GHTestWindow.nib differ diff --git a/Frameworks/GHUnit.framework/Versions/A/Resources/Info.plist b/Frameworks/GHUnit.framework/Versions/A/Resources/Info.plist new file mode 100644 index 00000000..18a013ce --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/A/Resources/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleExecutable + GHUnit + CFBundleIdentifier + me.rel.GHUnit + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + GHUnit + CFBundlePackageType + FMWK + CFBundleSignature + GABE + CFBundleVersion + 0.3.8 + + diff --git a/Frameworks/GHUnit.framework/Versions/Current b/Frameworks/GHUnit.framework/Versions/Current new file mode 120000 index 00000000..8c7e5a66 --- /dev/null +++ b/Frameworks/GHUnit.framework/Versions/Current @@ -0,0 +1 @@ +A \ No newline at end of file diff --git a/Frameworks/libGHUnitIPhone/GHAsyncTestCase.h b/Frameworks/libGHUnitIPhone/GHAsyncTestCase.h new file mode 100644 index 00000000..29622228 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHAsyncTestCase.h @@ -0,0 +1,123 @@ +// +// GHAsyncTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 4/8/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestCase.h" + +// Some default statuses to use; Or define and use your own +enum { + kGHUnitWaitStatusUnknown = 0, + kGHUnitWaitStatusSuccess, + kGHUnitWaitStatusFailure, + kGHUnitWaitStatusCancelled +}; + +/*! + Asynchronous test case with wait and notify. + + Handles the case of notify occuring before wait has started (if it was a synchronous call). + Be sure to call prepare before the asynchronous method (otherwise an exception will raise). + + @code + - (void)testSuccess { + [self prepare]; + + // Do asynchronous task here + [self performSelector:@selector(_succeed) withObject:nil afterDelay:0.1]; + + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + + - (void)_succeed { + // Notice the forSelector points to the test above. This is so that + // stray notifies don't error or falsely succeed other tests. + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testSuccess)]; + } + @endcode + */ +@interface GHAsyncTestCase : GHTestCase { + + NSInteger waitForStatus_; + NSInteger notifiedStatus_; + + BOOL prepared_; // Whether prepared was called before waitFor:timeout: + NSRecursiveLock *lock_; // Lock to synchronize on + SEL waitSelector_; // The selector we are waiting on + + NSArray *_runLoopModes; // Run loop modes to run while waiting; Defaults to NSDefaultRunLoopMode, NSRunLoopCommonModes, NSConnectionReplyMode +} + +@property (retain) NSArray *runLoopModes; + +/*! + Prepare before calling the asynchronous method. + */ +- (void)prepare; + +/*! + Prepare and specify the selector we will use in notify. + + @param selector + */ +- (void)prepare:(SEL)selector; + +/*! + Wait for notification of status or timeout. + + Be sure to prepare before calling your asynchronous method. + For example, + + @code + - (void)testFoo { + [self prepare]; + // Do asynchronous task here + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + @endcode + + @param status kGHUnitWaitStatusSuccess, kGHUnitWaitStatusFailure or custom status + @param timeout Timeout in seconds + */ +- (void)waitFor:(NSInteger)status timeout:(NSTimeInterval)timeout; + +/*! + Wait for timeout to occur. + Fails if we did _NOT_ timeout. + @param timeout + */ +- (void)waitForTimeout:(NSTimeInterval)timeout; + +/*! + Notify of status for test selector. + @param status For example, kGHUnitWaitStatusSuccess + @param selector If not NULL, then will verify this selector is where we are waiting. + This prevents stray asynchronous callbacks to fail a later test + */ +- (void)notify:(NSInteger)status forSelector:(SEL)selector; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHMockNSHTTPURLResponse.h b/Frameworks/libGHUnitIPhone/GHMockNSHTTPURLResponse.h new file mode 100644 index 00000000..d0b1aad9 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHMockNSHTTPURLResponse.h @@ -0,0 +1,46 @@ +// +// GHMockNSHTTPURLResponse.h +// GHUnit +// +// Created by Gabriel Handford on 4/9/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +/*! + NSHTTPURLResponse for use with mocking. + Allows us to manually set the status code and headers in the response. + */ +@interface GHMockNSHTTPURLResponse : NSHTTPURLResponse { + NSInteger statusCode_; + NSDictionary *headers_; +} + +- (id)initWithStatusCode:(NSInteger)statusCode headers:(NSDictionary *)headers; + +- (void)setStatusCode:(NSInteger)code; +- (void)setHeaders:(NSDictionary *)headers; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHMockNSURLConnection.h b/Frameworks/libGHUnitIPhone/GHMockNSURLConnection.h new file mode 100644 index 00000000..0b511abe --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHMockNSURLConnection.h @@ -0,0 +1,143 @@ +// +// GHMockNSURLConnection.h +// GHUnit +// +// Created by Gabriel Handford on 4/9/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import + +extern NSString *const GHMockNSURLConnectionException; + +/*! + NSURLConnection for mocking. + + Use with GHAsyncTestCase to mock out connections. + + @code + + @interface GHNSURLConnectionMockTest : GHAsyncTestCase {} + @end + + @implementation GHNSURLConnectionMockTest + + - (void)testMock { + [self prepare]; + GHMockNSURLConnection *connection = [[GHMockNSURLConnection alloc] initWithRequest:nil delegate:self]; + [connection receiveHTTPResponseWithStatusCode:204 headers:testHeaders_ afterDelay:0.1]; + [connection receiveData:testData_ afterDelay:0.2]; + [connection finishAfterDelay:0.3]; + [self waitFor:kGHUnitWaitStatusSuccess timeout:1.0]; + } + + - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + GHAssertEquals([(NSHTTPURLResponse *)response statusCode], 204, nil); + GHAssertEqualObjects([(NSHTTPURLResponse *)response allHeaderFields], testHeaders_, nil); + } + + - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + GHAssertEqualObjects(data, testData_, nil); + } + + - (void)connectionDidFinishLoading:(NSURLConnection *)connection { + [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testMock)]; + } + @end + + @endcode + */ +@interface GHMockNSURLConnection : NSObject { + NSURLRequest *request_; + id delegate_; // weak + + BOOL cancelled_; + BOOL started_; +} + +@property (readonly, nonatomic, getter=isStarted) BOOL started; +@property (readonly, nonatomic, getter=isCancelled) BOOL cancelled; + +// Mocked version of NSURLConnection#initWithRequest:delegate: +- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate; + +// Mocked version of NSURLConnection#initWithRequest:delegate:startImmediately: +- (id)initWithRequest:(NSURLRequest *)request delegate:(id)delegate startImmediately:(BOOL)startImmediately; + +// Mocked version of NSURLConnection#scheduleInRunLoop:forMode: (NOOP) +- (void)scheduleInRunLoop:(NSRunLoop *)aRunLoop forMode:(NSString *)mode; + +// Mocked version of NSURLConnection#start (NOOP) +- (void)start; + +/*! + Send generic response to delegate after delay. + (For asynchronous requests) + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)receiveResponse:(NSURLResponse *)response afterDelay:(NSTimeInterval)delay; + +/*! + Send HTTP response to delegate with status code, headers, after delay. + This is only the HTTP response (and not data or finished). + (For asynchronous requests) + @param statusCode HTTP status code + @param headers Headers + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)receiveHTTPResponseWithStatusCode:(int)statusCode headers:(NSDictionary *)headers afterDelay:(NSTimeInterval)delay; + +/*! + Send data to connection delegate after delay. + @param data Data to send + @param delay Delay in seconds + */ +- (void)receiveData:(NSData *)data afterDelay:(NSTimeInterval)delay; + +/*! + Send data (from file in bundle resource) to connection delegate after delay. + (For asynchronous requests) + @param path Path to file + @param delay Delay in seconds + */ +- (void)receiveDataFromPath:(NSString *)path afterDelay:(NSTimeInterval)delay; + +/*! + Calls connectionDidFinish: delegate after delay. + (For asynchronous requests) + @param delay Delay in seconds (if < 0, there is no delay) + */ +- (void)finishAfterDelay:(NSTimeInterval)delay; + +/*! + Sends mock response, sends data, and then calls finish. + (For asynchronous requests) + @param path Data to load path from. File should be available in Test target (bundle) + @param statusCode Status code for response + @param MIMEType Content type for response header + @param afterDelay Delay before responding (if < 0, there is no delay) + */ +- (void)receiveFromPath:(NSString *)path statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType afterDelay:(NSTimeInterval)delay; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHNSLocale+Mock.h b/Frameworks/libGHUnitIPhone/GHNSLocale+Mock.h new file mode 100644 index 00000000..41cc02a0 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHNSLocale+Mock.h @@ -0,0 +1,59 @@ +// +// GHMockNSLocale.h +// GHUnitIPhone +// +// Created by Gabriel Handford on 4/13/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +/*! + Category for overriding the current locale at runtime. + + @code + #import "GHNSLocale+Mock.h" + // This aliases the currentLocale method and with the specified locale identifier + [NSLocale gh_setLocaleIdentifier:@"en_GB"]; + + [[NSLocale currentLocale] localeIdentifier] == "en_GB" + @endcode + */ +@interface NSLocale (GHMock) + ++ (void)gh_setLocaleIdentifier:(NSString *)localeIdentifier; + +/*! + Aliases to currentLocale with locale set from gh_setLocaleIdentifier. + If not set, defaults to NSLocale with identifier en_US. + */ ++ (NSLocale *)gh_currentLocale; + ++ (void)gh_setPreferredLanguages:(NSArray *)preferredLanguages; + +/*! + Aliases to preferredLanguages set from gh_setPreferredLanguages. + If not set, defaults to [@"en"]. + */ ++ (NSArray *)gh_preferredLanguages; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHTest.h b/Frameworks/libGHUnitIPhone/GHTest.h new file mode 100644 index 00000000..d1535f57 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTest.h @@ -0,0 +1,171 @@ +// +// GHTest.h +// GHKit +// +// Created by Gabriel Handford on 1/18/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +/*! + Test status. + */ +typedef enum { + GHTestStatusNone = 0, + GHTestStatusRunning, + GHTestStatusFinished, + GHTestStatusIgnored +} GHTestStatus; + +/*! + Generate string from GHTestStatus + @param status + */ +NSString* NSStringFromGHTestStatus(GHTestStatus status); + +/*! + Test stats. + */ +typedef struct { + NSInteger runCount; + NSInteger failureCount; + NSInteger ignoreCount; + NSInteger testCount; +} GHTestStats; + +/*! + Create GHTestStats. + */ +GHTestStats GHTestStatsMake(NSInteger runCount, NSInteger failureCount, NSInteger ignoreCount, NSInteger testCount); + +#define NSStringFromGHTestStats(stats) [NSString stringWithFormat:@"%d/%d/%d", stats.runCount, stats.testCount, stats.failureCount] + +@protocol GHTestDelegate; + +/*! + The base interface for a runnable test. + A runnable with a unique identifier, display name, stats, timer, delegate, log and error handling. + */ +@protocol GHTest + +- (void)run; + +- (NSString *)identifier; +- (NSString *)name; + +- (NSTimeInterval)interval; +- (GHTestStatus)status; +- (GHTestStats)stats; + +- (void)setDelegate:(id)delegate; + +- (NSException *)exception; + +- (NSArray *)log; + +- (BOOL)ignore; +- (void)setIgnore:(BOOL)ignore; + +@end + +/*! + Test delegate for notification when a test starts and ends. + */ +@protocol GHTestDelegate +- (void)testDidStart:(id)test; +- (void)testDidFinish:(id)test; +- (void)test:(id)test didLog:(NSString *)message; +- (void)testDidIgnore:(id)test; +@end + +/*! + Delegate which is notified of log messages from inside GHTestCase. + */ +@protocol GHTestCaseLogDelegate +- (void)testCase:(id)testCase didLog:(NSString *)message; +@end + +/*! + Default test implementation target with a target/selector pair. + - Consists of a target/selector + - Notifies a test delegate + - Keeps track of status, running time and failures + - Stores any test specific logging + */ +@interface GHTest : NSObject { + + id delegate_; // weak + + id target_; + SEL selector_; + + NSString *identifier_; + NSString *name_; + GHTestStatus status_; + NSTimeInterval interval_; + BOOL failed_; + NSException *exception_; // If failed + + GHTestStats stats_; + + NSMutableArray *log_; + + BOOL ignore_; +} + +/*! + Create test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ +- (id)initWithTarget:(id)target selector:(SEL)selector; + +/*! + Create autoreleased test with target/selector. + @param target Target (usually a test case) + @param selector Selector (usually a test method) + */ ++ (id)testWithTarget:(id)target selector:(SEL)selector; + +@property (readonly, nonatomic) id target; +@property (readonly, nonatomic) SEL selector; +@property (readonly, nonatomic) NSString *identifier; // Unique identifier for test +@property (readonly, nonatomic) NSString *name; +@property (readonly, nonatomic) NSTimeInterval interval; +@property (readonly, nonatomic) NSException *exception; +@property (readonly, nonatomic) GHTestStatus status; +@property (readonly, nonatomic) BOOL failed; +@property (readonly, nonatomic) GHTestStats stats; +@property (readonly, nonatomic) NSArray *log; + +@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) BOOL ignore; + +/*! + Run the test. + After running, the interval and exception properties may be set. + @result YES if passed, NO otherwise + */ +- (void)run; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHTestCase.h b/Frameworks/libGHUnitIPhone/GHTestCase.h new file mode 100644 index 00000000..9472a494 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTestCase.h @@ -0,0 +1,133 @@ +// +// GHTestCase.h +// GHUnit +// +// Created by Gabriel Handford on 1/21/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTestMacros.h" +#import "GHTest.h" + +// Log to your test case logger. +// For example, GHTestLog(@"Some debug info, %@", obj) +#define GHTestLog(...) [self log:[NSString stringWithFormat:__VA_ARGS__, nil]] + +/*! + @brief The base class for a test case. + + @code + @interface MyTest : GHTestCase {} + @end + + @implementation MyTest + + // Run before each test method + - (void)setUp { } + + // Run after each test method + - (void)tearDown { } + + // Run before the tests are run for this class + - (void)setUpClass { } + + // Run before the tests are run for this class + - (void)tearDownClass { } + + // Tests are prefixed by 'test' and contain no arguments and no return value + - (void)testA { + GHTestLog(@"Log with a test with the GHTestLog(...) for test specific logging."); + } + + // Another test; Tests are run in lexical order + - (void)testB { } + + // Override any exceptions; By default exceptions are raised, causing a test failure + - (void)failWithException:(NSException*)exception { } + + @end + @endcode + + */ +@interface GHTestCase : NSObject { + id logDelegate_; // weak + + SEL currentSelector_; +} + +//! The current test selector +@property (assign, nonatomic) SEL currentSelector; +@property (assign, nonatomic) id logDelegate; + +// GTM_BEGIN +//! Run before each test method +- (void)setUp; + +//! Run after each test method +- (void)tearDown; + +/*! + By default exceptions are raised, causing a test failure + @brief Override any exceptions + @param exception Exception that was raised by test + */ +- (void)failWithException:(NSException*)exception; +// GTM_END + +//! Run before the tests (once per test case) +- (void)setUpClass; + +//! Run after the tests (once per test case) +- (void)tearDownClass; + +//! Any special handling of exceptions after they are thrown; By default logs stack trace to standard out. +- (void)handleException:(NSException *)exception; + +/*! + Log a message, which notifies the log delegate. + This is not meant to be used directly, see GHTestLog(...) macro. + @param message + */ +- (void)log:(NSString *)message; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHTestGroup.h b/Frameworks/libGHUnitIPhone/GHTestGroup.h new file mode 100644 index 00000000..25783585 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTestGroup.h @@ -0,0 +1,164 @@ +// +// GHTestGroup.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTest.h" +#import "GHTestCase.h" + +/*! + @brief Interface for a group of tests. + + This group conforms to the GHTest protocol as well (see Composite pattern). + */ +@protocol GHTestGroup +- (NSString *)name; +- (id)parent; +- (NSArray *)children; +@end + +/*! + @brief A collection of tests (or test groups). + + A test group is a collection of id, that may represent a set of test case methods. + + For example, if you had the following GHTestCase. + + @code + @interface FooTest : GHTestCase {} + - (void)testFoo; + - (void)testBar; + @end + @endcode + + The GHTestGroup would consist of and array of GHTest, [FooTest#testFoo and FooTest#testBar], + each test being a target and selector pair. + + A test group may also consist of a group of groups (since GHTestGroup conforms to GHTest), + and this might represent a GHTestSuite. + */ +@interface GHTestGroup : NSObject { + + id delegate_; // weak + id parent_; // weak + + NSMutableArray *children_; // of id + + NSString *name_; // The name of the test group (usually the class name of the test case + NSTimeInterval interval_; // Total time of child tests + GHTestStatus status_; // Current status of the group (current status of running or completed child tests) + GHTestStats stats_; // Current stats for the group (aggregate of child test stats) + + id testCase_; // Is set if test is created from initWithTestCase:delegate: + id currentTest_; // weak + + NSException *exception_; // If exception happens in group setUpClass/tearDownClass + + BOOL ignore_; +} + +@property (readonly, nonatomic) NSArray *children; +@property (assign, nonatomic) id delegate; +@property (assign, nonatomic) id parent; +@property (readonly, nonatomic) id testCase; + +@property (readonly, nonatomic) NSString *identifier; +@property (readonly, nonatomic) NSString *name; +@property (readonly, nonatomic) GHTestStatus status; + +@property (readonly, nonatomic) NSTimeInterval interval; +@property (readonly, nonatomic) GHTestStats stats; + +@property (assign, nonatomic) BOOL ignore; + +/*! + Create an empty test group. + @param name The name of the test group + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithName:(NSString *)name delegate:(id)delegate; + +/*! + Create test group from a test case. + + A test group is a collection of GHTest. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ +- (id)initWithTestCase:(id)testCase delegate:(id)delegate; + +/*! + Create test group from a single test. + @param testCase + @param selector Test to run + @param delegate + */ +- (id)initWithTestCase:(id)testCase selector:(SEL)selector delegate:(id)delegate; + +/*! + Create test group from a test case. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + @param delegate Delegate, notifies of test start and end + @result New test group + */ ++ (GHTestGroup *)testGroupFromTestCase:(id)testCase delegate:(id)delegate; + +/*! + Add a test case (or test group) to this test group. + @param testCase Test case, could be a subclass of SenTestCase or GHTestCase + */ +- (void)addTestCase:(id)testCase; + +- (void)addTestGroup:(GHTestGroup *)testGroup; + +/*! + Run the test group. + Will notify delegate as tests are run. + */ +- (void)run; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHTestMacros.h b/Frameworks/libGHUnitIPhone/GHTestMacros.h new file mode 100644 index 00000000..b8080d1f --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTestMacros.h @@ -0,0 +1,1004 @@ +// +// GHTestMacros.h +// +// Created by Gabriel Handford on 1/17/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// 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. + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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. +// + +// GTM_BEGIN + +extern NSString *const GHTestFilenameKey; +extern NSString *const GHTestLineNumberKey; +extern NSString *const GHTestFailureException; + +NSString *GHComposeString(NSString *, ...); + +// 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 GHAssertNoErr(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, GHComposeString(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:GHComposeString(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 GHAssertErr(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, GHComposeString(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) fails", #a1, #a2] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + + +// Generates a failure when a1 is NULL +// Args: +// a1: should be a pointer (use GHAssertNotNil 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 GHAssertNotNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value == NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) != NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when a1 is not NULL +// Args: +// a1: should be a pointer (use GHAssertNil 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 GHAssertNULL(a1, description, ...) \ +do { \ +@try {\ +const void* a1value = (a1); \ +if (a1value != NULL) { \ +NSString *_expression = [NSString stringWithFormat:@"(%s) == NULL", #a1]; \ +if (description) { \ +_expression = [NSString stringWithFormat:@"%@: %@", _expression, GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when a1 is equal 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 GHAssertNotEquals(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:GHComposeString(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, GHComposeString(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:GHComposeString(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 GHAssertNotEqualObjects(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, GHComposeString(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:GHComposeString(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 GHAssertOperation(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:GHComposeString(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, GHComposeString(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:GHComposeString(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 GHAssertGreaterThan(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertGreaterThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertLessThan(a1, a2, description, ...) \ +GHAssertOperation(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 GHAssertLessThanOrEqual(a1, a2, description, ...) \ +GHAssertOperation(a1, a2, <=, description, ##__VA_ARGS__) + +// Generates a failure when string a1 is not equal to string a2. This call +// differs from GHAssertEqualObjects 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 GHAssertEqualStrings(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// Generates a failure when string a1 is equal to string a2. This call +// differs from GHAssertEqualObjects 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 GHAssertNotEqualStrings(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: GHComposeString(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:GHComposeString(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 GHAssertEqualCStrings(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: GHComposeString(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:GHComposeString(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 GHAssertNotEqualCStrings(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +// GTM_END + +// 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 GHAssertEqualObjects(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: GHComposeString(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:GHComposeString(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 GHAssertEquals(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:GHComposeString(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: GHComposeString(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:GHComposeString(description, ##__VA_ARGS__)]]; \ +}\ +} while(0) + +#define GHAbsoluteDifference(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 GHAssertEqualsWithAccuracy(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:GHComposeString(description, ##__VA_ARGS__)]]]; \ +} else { \ +__typeof__(a1) a1value = (a1); \ +__typeof__(a2) a2value = (a2); \ +__typeof__(accuracy) accuracyvalue = (accuracy); \ +if (GHAbsoluteDifference(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: GHComposeString(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:GHComposeString(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 GHFail(description, ...) \ +[self failWithException:[NSException failureInFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(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 GHAssertNil(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: GHComposeString(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:GHComposeString(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 GHAssertNotNil(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: GHComposeString(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:GHComposeString(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 GHAssertTrue(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: GHComposeString(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 GHAssertTrueNoThrow(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: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(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 GHAssertFalse(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: GHComposeString(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 GHAssertFalseNoThrow(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: GHComposeString(description, ##__VA_ARGS__)]]; \ +} \ +} \ +@catch (id anException) {\ +[self failWithException:[NSException failureInRaise:[NSString stringWithFormat: @"!(%s) ", #expr] \ +exception:anException \ +inFile:[NSString stringWithUTF8String:__FILE__] \ +atLine:__LINE__ \ +withDescription:GHComposeString(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 GHAssertThrows(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: GHComposeString(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 GHAssertThrowsSpecific(expr, specificException, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_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 GHAssertThrowsSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) continue; \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +@catch (id anException) {\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +continue; \ +}\ +NSString *_descrip = GHComposeString(@"(Expected exception: %@) %@", NSStringFromClass([specificException class]), description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: nil \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_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 GHAssertNoThrow(expr, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (id anException) { \ +[self failWithException:[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(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 GHAssertNoThrowSpecific(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: GHComposeString(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 GHAssertNoThrowSpecificNamed(expr, specificException, aName, description, ...) \ +do { \ +@try { \ +(expr);\ +} \ +@catch (specificException *anException) { \ +if ([aName isEqualToString: [anException name]]) { \ +NSString *_descrip = GHComposeString(@"(Expected exception: %@ (name: %@)) %@", NSStringFromClass([specificException class]), aName, description);\ +[self failWithException: \ +[NSException failureInRaise: [NSString stringWithUTF8String:#expr] \ +exception: anException \ +inFile: [NSString stringWithUTF8String:__FILE__] \ +atLine: __LINE__ \ +withDescription: GHComposeString(_descrip, ##__VA_ARGS__)]]; \ +} \ +continue; \ +}\ +@catch (id anythingElse) {\ +; \ +}\ +} while (0) + + +@interface NSException (GHTestMacros_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 diff --git a/Frameworks/libGHUnitIPhone/GHTestRunner.h b/Frameworks/libGHUnitIPhone/GHTestRunner.h new file mode 100644 index 00000000..132e9e8f --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTestRunner.h @@ -0,0 +1,131 @@ +// +// GHTestRunner.h +// +// Created by Gabriel Handford on 1/16/09. +// Copyright 2008 Gabriel Handford +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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 "GHTestGroup.h" +#import "GHTestSuite.h" + +@class GHTestRunner; + +// Delegates can be guaranteed to be notified on the main thread (using #delegateOnMainThread) +@protocol GHTestRunnerDelegate +@optional +- (void)testRunnerDidStart:(GHTestRunner *)runner; +- (void)testRunner:(GHTestRunner *)runner didStartTest:(id)test; +- (void)testRunner:(GHTestRunner *)runner didFinishTest:(id)test; +- (void)testRunnerDidFinish:(GHTestRunner *)runner; + +- (void)testRunner:(GHTestRunner *)runner didLog:(NSString *)message; +- (void)testRunner:(GHTestRunner *)runner test:(id)test didLog:(NSString *)message; +@end + +/*! + Runs the tests. + Tests are run a separate thread though delegates are called on the + main thread by default (see #delegateOnMainThread). + */ +@interface GHTestRunner : NSObject { + + id test_; // The test to run; Could be a GHTestGroup (suite), GHTestGroup (test case), or GHTest (target/selector) + + id delegate_; // weak + + // If YES, will allow exceptions to be raised (so you can trigger the debugger) + BOOL raiseExceptions_; + + // If yes, delegate calls will occur on the main thread + // Defaults to YES. + BOOL delegateOnMainThread_; + +} + +@property (retain) id test; +@property (assign) id delegate; +@property (assign) BOOL raiseExceptions; +@property (assign) BOOL delegateOnMainThread; +@property (readonly) GHTestStats stats; + +/*! + Create runner for test. + @param test + */ +- (id)initWithTest:(id)test; + +/*! + Create runner for all tests. + @see GHTesting#loadAllTestCases. + @result Runner + */ ++ (GHTestRunner *)runnerForAllTests; + +/*! + Create runner for test suite. + @param suite + @result Runner + */ ++ (GHTestRunner *)runnerForSuite:(GHTestSuite *)suite; + +/*! + Get the runner from the environment. + If the TEST env is set, then we will only run that test case or test method. + */ ++ (GHTestRunner *)runnerFromEnv; + +/*! + Run the test runner. Usually called from the test main. + Reads the TEST environment variable and filters on that; or all tests are run. + @result Return value, 0 is success, otherwise the failure count + */ ++ (int)run; + +/*! + Start the test runner. + */ +- (void)run; + +@end + + diff --git a/Frameworks/libGHUnitIPhone/GHTestSuite.h b/Frameworks/libGHUnitIPhone/GHTestSuite.h new file mode 100644 index 00000000..e80ef32a --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTestSuite.h @@ -0,0 +1,88 @@ +// +// GHTestSuite.h +// GHUnit +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestGroup.h" + +/*! + Test suite is an alias for test group. + + A test case is an instance of a test case class with test methods. + A test is a id which represents a target and a selector. + A test group is a collection of tests; A collection of id (GHTest or GHTestGroup). + + For example, if you have 2 test cases, GHTestCase1 (with some test methods) and GHTestCase2 (with some test methods), + your test suite might look like: + +"Tests" (GHTestSuite) + GHTestGroup (collection of tests from GHTestCase1) + - (void)testA1 (GHTest with target GHTestCase1 + testA1) + - (void)testA2 (GHTest with target GHTestCase1 + testA2) + GHTestGroup (collection of tests from GHTestCase2) + - (void)testB1; (GHTest with target GHTestCase2 + testB1) + - (void)testB2; (GHTest with target GHTestCase2 + testB2) + + */ +@interface GHTestSuite : GHTestGroup { + +} + +/*! + Create test suite with test cases. + @param name Label to give the suite + @param testCases Array of init'ed test case classes + @param delegate + */ +- (id)initWithName:(NSString *)name testCases:(NSArray *)testCases delegate:(id)delegate; + +/*! + Creates a suite of all tests. + Will load all classes that subclass from GHTestCase, SenTestCase or GTMTestCase (or register test case class). + */ ++ (GHTestSuite *)allTests; + +/*! + Create suite of tests with filter. + This is useful for running a single test or all tests in a single test case. + + For example, + 'GHSlowTest' -- Runs all test method in GHSlowTest + 'GHSlowTest/testSlowA -- Only runs the test method testSlowA in GHSlowTest + + @param testFilter Test filter + @result Suite + */ ++ (GHTestSuite *)suiteWithTestFilter:(NSString *)testFilter; + +/*! + Return test suite based on environment (TEST=TestFoo/foo) + @result Suite + */ ++ (GHTestSuite *)suiteFromEnv; + +@end diff --git a/Frameworks/libGHUnitIPhone/GHTesting.h b/Frameworks/libGHUnitIPhone/GHTesting.h new file mode 100644 index 00000000..16ddc3b0 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHTesting.h @@ -0,0 +1,104 @@ +// +// GHTesting.h +// GHUnit +// +// Created by Gabriel Handford on 1/30/09. +// Copyright 2008 Gabriel Handford +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +// +// Portions of this file fall under the following license, marked with: +// GTM_BEGIN : GTM_END +// +// 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. +// + +// GTM_BEGIN +BOOL isTestFixtureOfClass(Class aClass, Class testCaseClass); +// GTM_END + +/*! + Utility test for loading and running tests. + @note Much of this is borrowed from GTM/UnitTesting. + */ +@interface GHTesting : NSObject { + + NSMutableArray/* of NSString*/ *testCaseClassNames_; + +} + +/*! + The shared testing instance. + */ ++ (GHTesting *)sharedInstance; + +/*! + Load all test classes that we can "see". + @return Array of initialized (and autoreleased) test case classes in an autoreleased array. + */ +- (NSArray *)loadAllTestCases; + +/*! + Load tests from target. + @result Array of id + */ +- (NSArray *)loadTestsFromTarget:(id)target; + +/*! + See if class is of a registered test case class. + */ +- (BOOL)isTestCaseClass:(Class)aClass; + +/*! + Register test case class. + @param aClass + */ +- (void)registerClass:(Class)aClass; + +/*! + Register test case class by name. + @param className Class name (via NSStringFromClass(aClass) + */ +- (void)registerClassName:(NSString *)className; + +/*! + Run test. + Exception if set is retained and should be released by the caller. + */ +- (BOOL)runTest:(id)target selector:(SEL)selector exception:(NSException **)exception interval:(NSTimeInterval *)interval; + +@end + diff --git a/Frameworks/libGHUnitIPhone/GHUNSObject+Swizzle.h b/Frameworks/libGHUnitIPhone/GHUNSObject+Swizzle.h new file mode 100644 index 00000000..77d9a197 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHUNSObject+Swizzle.h @@ -0,0 +1,36 @@ +// +// GHNSObject+Swizzle.h +// GHUnit +// +// Created by Gabriel Handford on 4/13/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +@interface NSObject (GHUSwizzle) + ++ (void)ghu_swizzleMethod:(SEL)original withMethod:(SEL)alternate; ++ (void)ghu_swizzleClassMethod:(SEL)original withClassMethod:(SEL)alternate; + +@end + diff --git a/Frameworks/libGHUnitIPhone/GHUnit.h b/Frameworks/libGHUnitIPhone/GHUnit.h new file mode 100644 index 00000000..1501d04b --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHUnit.h @@ -0,0 +1,34 @@ +// +// GHUnit.h +// GHUnit +// +// Created by Gabriel Handford on 1/19/09. +// Copyright 2009. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +// + +#import "GHTestCase.h" +#import "GHAsyncTestCase.h" +#import "GHTestSuite.h" +#import "GHTestMacros.h" +#import "GHTestRunner.h" diff --git a/Frameworks/libGHUnitIPhone/GHUnitIPhoneTestMain.m b/Frameworks/libGHUnitIPhone/GHUnitIPhoneTestMain.m new file mode 100644 index 00000000..ac5e25f2 --- /dev/null +++ b/Frameworks/libGHUnitIPhone/GHUnitIPhoneTestMain.m @@ -0,0 +1,36 @@ +// +// GHUnitIPhoneTestMain.m +// GHUnitIPhone +// +// Created by Gabriel Handford on 1/25/09. +// Copyright 2009. All rights reserved. +// + +#import +#import +#import "GHUnit.h" + +int main(int argc, char *argv[]) { + // Setup any NSDebug settings + NSDebugEnabled = YES; + NSZombieEnabled = YES; + NSDeallocateZombies = NO; + NSHangOnUncaughtException = YES; + setenv("NSAutoreleaseFreedObjectCheckEnabled", "1", 1); + + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; + + // Register any special test case classes + //[[GHTesting sharedInstance] registerClassName:@"GHSpecialTestCase"]; + + int retVal = 0; + // If GHUNIT_CLI is set we are using the command line interface and run the tests + // Otherwise load the GUI app + if (getenv("GHUNIT_CLI")) { + retVal = [GHTestRunner run]; + } else { + retVal = UIApplicationMain(argc, argv, nil, @"GHUnitIPhoneAppDelegate"); + } + [pool release]; + return retVal; +} diff --git a/Frameworks/libGHUnitIPhone/RunTests.sh b/Frameworks/libGHUnitIPhone/RunTests.sh new file mode 100755 index 00000000..5616369c --- /dev/null +++ b/Frameworks/libGHUnitIPhone/RunTests.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# If we aren't running from the command line, then exit +if [ "$GHUNIT_CLI" != "1" ]; then + exit 0 +fi + +export DYLD_ROOT_PATH="$SDKROOT" +export DYLD_FRAMEWORK_PATH="$CONFIGURATION_BUILD_DIR" + +"$TARGET_BUILD_DIR/$EXECUTABLE_PATH" -RegisterForSystemEvents +RETVAL=$? + +exit $RETVAL + + + diff --git a/Frameworks/libGHUnitIPhone/libGHUnitIPhone.a b/Frameworks/libGHUnitIPhone/libGHUnitIPhone.a new file mode 100644 index 00000000..fc39a018 Binary files /dev/null and b/Frameworks/libGHUnitIPhone/libGHUnitIPhone.a differ diff --git a/Mac.xcodeproj/project.pbxproj b/Mac.xcodeproj/project.pbxproj index 6ce11f02..5c2de490 100644 --- a/Mac.xcodeproj/project.pbxproj +++ b/Mac.xcodeproj/project.pbxproj @@ -16,30 +16,6 @@ B55B5E7F0F76573B0064029C /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = B55B5E730F7656DA0064029C /* MainMenu.xib */; }; B55B5EB80F7658200064029C /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B55B5EB70F7658200064029C /* libz.1.2.3.dylib */; }; B55B5ED20F76588D0064029C /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5ED10F76588D0064029C /* AppDelegate.m */; }; - B55B5FE80F76594D0064029C /* GHTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FAC0F76594D0064029C /* GHTest.m */; }; - B55B5FE90F76594D0064029C /* GHTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FAE0F76594D0064029C /* GHTestCase.m */; }; - B55B5FEA0F76594D0064029C /* GHTestGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FB00F76594D0064029C /* GHTestGroup.m */; }; - B55B5FEB0F76594D0064029C /* GHTestMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FB20F76594D0064029C /* GHTestMacros.m */; }; - B55B5FEC0F76594D0064029C /* GHTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FB40F76594D0064029C /* GHTestRunner.m */; }; - B55B5FED0F76594D0064029C /* GHTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FB60F76594D0064029C /* GHTestSuite.m */; }; - B55B5FEE0F76594D0064029C /* GHTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FB80F76594D0064029C /* GHTestUtils.m */; }; - B55B5FEF0F76594D0064029C /* RunTests.sh in Resources */ = {isa = PBXBuildFile; fileRef = B55B5FBA0F76594D0064029C /* RunTests.sh */; }; - B55B5FF00F76594D0064029C /* GHTestViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FBD0F76594D0064029C /* GHTestViewModel.m */; }; - B55B5FF10F76594D0064029C /* GHLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FC10F76594D0064029C /* GHLogger.m */; }; - B55B5FF20F76594D0064029C /* GHNSInvocation+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FC30F76594D0064029C /* GHNSInvocation+Utils.m */; }; - B55B5FF30F76594D0064029C /* GHNSObject+Invocation.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FC50F76594D0064029C /* GHNSObject+Invocation.m */; }; - B55B5FF40F76594D0064029C /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FCA0F76594D0064029C /* GTMLogger.m */; }; - B55B5FF50F76594D0064029C /* GTMObjC2Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FCC0F76594D0064029C /* GTMObjC2Runtime.m */; }; - B55B5FF60F76594D0064029C /* GTMStackTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FCE0F76594D0064029C /* GTMStackTrace.m */; }; - B55B5FF70F76594D0064029C /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B55B5FD00F76594D0064029C /* README.md */; }; - B55B5FF80F76594D0064029C /* GHUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FD20F76594D0064029C /* GHUnitTestMain.m */; }; - B55B5FF90F76594D0064029C /* GHTestApp.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FD50F76594D0064029C /* GHTestApp.m */; }; - B55B5FFA0F76594D0064029C /* GHTestApp.xib in Resources */ = {isa = PBXBuildFile; fileRef = B55B5FD60F76594D0064029C /* GHTestApp.xib */; }; - B55B5FFB0F76594D0064029C /* GHTestAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FD80F76594D0064029C /* GHTestAppDelegate.m */; }; - B55B5FFC0F76594D0064029C /* GHTestView.xib in Resources */ = {isa = PBXBuildFile; fileRef = B55B5FD90F76594D0064029C /* GHTestView.xib */; }; - B55B5FFD0F76594D0064029C /* GHTestViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FDB0F76594D0064029C /* GHTestViewController.m */; }; - B55B5FFE0F76594D0064029C /* GHTestWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = B55B5FDC0F76594D0064029C /* GHTestWindow.xib */; }; - B55B5FFF0F76594D0064029C /* GHTestWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5FDE0F76594D0064029C /* GHTestWindowController.m */; }; B55B60080F7659790064029C /* ASIFormDataRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5D1B0F76568E0064029C /* ASIFormDataRequestTests.m */; }; B55B60090F76597C0064029C /* ASIHTTPRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5D1D0F76568E0064029C /* ASIHTTPRequestTests.m */; }; B55B600A0F7659800064029C /* ASINetworkQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5D1F0F76568E0064029C /* ASINetworkQueueTests.m */; }; @@ -48,8 +24,24 @@ B55B600F0F7659900064029C /* ASIHTTPRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5D140F76568E0064029C /* ASIHTTPRequest.m */; }; B55B60100F7659960064029C /* ASIFormDataRequest.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B5D120F76568E0064029C /* ASIFormDataRequest.m */; }; B55B60140F7659A30064029C /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B55B5EB70F7658200064029C /* libz.1.2.3.dylib */; }; + B5B513680FBEE435002C74D0 /* GHUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B5B513670FBEE435002C74D0 /* GHUnit.framework */; }; + B5B513830FBEE490002C74D0 /* GHUnit.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = B5B513670FBEE435002C74D0 /* GHUnit.framework */; }; + B5B513860FBEE515002C74D0 /* GHUnitTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B513850FBEE515002C74D0 /* GHUnitTestMain.m */; }; /* End PBXBuildFile section */ +/* Begin PBXCopyFilesBuildPhase section */ + B5B513820FBEE477002C74D0 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + B5B513830FBEE490002C74D0 /* GHUnit.framework in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + /* Begin PBXFileReference section */ 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 13E42FB307B3F0F600E4EEF1 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = ""; }; @@ -79,51 +71,8 @@ B55B5ED00F76588D0064029C /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = "Mac Sample/AppDelegate.h"; sourceTree = ""; }; B55B5ED10F76588D0064029C /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = "Mac Sample/AppDelegate.m"; sourceTree = ""; }; B55B5EDF0F7658C70064029C /* Unit Tests (GHUnit).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Unit Tests (GHUnit).app"; sourceTree = BUILT_PRODUCTS_DIR; }; - B55B5FAB0F76594D0064029C /* GHTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTest.h; sourceTree = ""; }; - B55B5FAC0F76594D0064029C /* GHTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTest.m; sourceTree = ""; }; - B55B5FAD0F76594D0064029C /* GHTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestCase.h; sourceTree = ""; }; - B55B5FAE0F76594D0064029C /* GHTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestCase.m; sourceTree = ""; }; - B55B5FAF0F76594D0064029C /* GHTestGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestGroup.h; sourceTree = ""; }; - B55B5FB00F76594D0064029C /* GHTestGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestGroup.m; sourceTree = ""; }; - B55B5FB10F76594D0064029C /* GHTestMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestMacros.h; sourceTree = ""; }; - B55B5FB20F76594D0064029C /* GHTestMacros.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestMacros.m; sourceTree = ""; }; - B55B5FB30F76594D0064029C /* GHTestRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestRunner.h; sourceTree = ""; }; - B55B5FB40F76594D0064029C /* GHTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestRunner.m; sourceTree = ""; }; - B55B5FB50F76594D0064029C /* GHTestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestSuite.h; sourceTree = ""; }; - B55B5FB60F76594D0064029C /* GHTestSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestSuite.m; sourceTree = ""; }; - B55B5FB70F76594D0064029C /* GHTestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestUtils.h; sourceTree = ""; }; - B55B5FB80F76594D0064029C /* GHTestUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestUtils.m; sourceTree = ""; }; - B55B5FB90F76594D0064029C /* GHUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHUnit.h; sourceTree = ""; }; - B55B5FBA0F76594D0064029C /* RunTests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = RunTests.sh; sourceTree = ""; }; - B55B5FBC0F76594D0064029C /* GHTestViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestViewModel.h; sourceTree = ""; }; - B55B5FBD0F76594D0064029C /* GHTestViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestViewModel.m; sourceTree = ""; }; - B55B5FC00F76594D0064029C /* GHLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHLogger.h; sourceTree = ""; }; - B55B5FC10F76594D0064029C /* GHLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHLogger.m; sourceTree = ""; }; - B55B5FC20F76594D0064029C /* GHNSInvocation+Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GHNSInvocation+Utils.h"; sourceTree = ""; }; - B55B5FC30F76594D0064029C /* GHNSInvocation+Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GHNSInvocation+Utils.m"; sourceTree = ""; }; - B55B5FC40F76594D0064029C /* GHNSObject+Invocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GHNSObject+Invocation.h"; sourceTree = ""; }; - B55B5FC50F76594D0064029C /* GHNSObject+Invocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GHNSObject+Invocation.m"; sourceTree = ""; }; - B55B5FC80F76594D0064029C /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = ""; }; - B55B5FC90F76594D0064029C /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = ""; }; - B55B5FCA0F76594D0064029C /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = ""; }; - B55B5FCB0F76594D0064029C /* GTMObjC2Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMObjC2Runtime.h; sourceTree = ""; }; - B55B5FCC0F76594D0064029C /* GTMObjC2Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMObjC2Runtime.m; sourceTree = ""; }; - B55B5FCD0F76594D0064029C /* GTMStackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMStackTrace.h; sourceTree = ""; }; - B55B5FCE0F76594D0064029C /* GTMStackTrace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMStackTrace.m; sourceTree = ""; }; - B55B5FCF0F76594D0064029C /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; - B55B5FD00F76594D0064029C /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; - B55B5FD20F76594D0064029C /* GHUnitTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitTestMain.m; sourceTree = ""; }; - B55B5FD40F76594D0064029C /* GHTestApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestApp.h; sourceTree = ""; }; - B55B5FD50F76594D0064029C /* GHTestApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestApp.m; sourceTree = ""; }; - B55B5FD60F76594D0064029C /* GHTestApp.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GHTestApp.xib; sourceTree = ""; }; - B55B5FD70F76594D0064029C /* GHTestAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestAppDelegate.h; sourceTree = ""; }; - B55B5FD80F76594D0064029C /* GHTestAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestAppDelegate.m; sourceTree = ""; }; - B55B5FD90F76594D0064029C /* GHTestView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GHTestView.xib; sourceTree = ""; }; - B55B5FDA0F76594D0064029C /* GHTestViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestViewController.h; sourceTree = ""; }; - B55B5FDB0F76594D0064029C /* GHTestViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestViewController.m; sourceTree = ""; }; - B55B5FDC0F76594D0064029C /* GHTestWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GHTestWindow.xib; sourceTree = ""; }; - B55B5FDD0F76594D0064029C /* GHTestWindowController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestWindowController.h; sourceTree = ""; }; - B55B5FDE0F76594D0064029C /* GHTestWindowController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestWindowController.m; sourceTree = ""; }; + B5B513670FBEE435002C74D0 /* GHUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GHUnit.framework; path = Frameworks/GHUnit.framework; sourceTree = ""; }; + B5B513850FBEE515002C74D0 /* GHUnitTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitTestMain.m; sourceTree = ""; }; B5E3858B0F76606B00FD7857 /* Tests-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = "Tests-Info.plist"; path = "Mac Sample/Tests-Info.plist"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -142,6 +91,7 @@ buildActionMask = 2147483647; files = ( B55B60140F7659A30064029C /* libz.1.2.3.dylib in Frameworks */, + B5B513680FBEE435002C74D0 /* GHUnit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -151,6 +101,7 @@ 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { isa = PBXGroup; children = ( + B5B513670FBEE435002C74D0 /* GHUnit.framework */, 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, ); name = "Linked Frameworks"; @@ -222,7 +173,6 @@ B55B5D100F76568E0064029C /* Classes */ = { isa = PBXGroup; children = ( - B55B5FA30F7659360064029C /* GHUnit */, B55B5D110F76568E0064029C /* ASIFormDataRequest.h */, B55B5D120F76568E0064029C /* ASIFormDataRequest.m */, B55B5D130F76568E0064029C /* ASIHTTPRequest.h */, @@ -239,6 +189,7 @@ B55B5D190F76568E0064029C /* Tests */ = { isa = PBXGroup; children = ( + B5B513850FBEE515002C74D0 /* GHUnitTestMain.m */, B55B5D1A0F76568E0064029C /* ASIFormDataRequestTests.h */, B55B5D1B0F76568E0064029C /* ASIFormDataRequestTests.m */, B55B5D1C0F76568E0064029C /* ASIHTTPRequestTests.h */, @@ -249,125 +200,6 @@ path = Tests; sourceTree = ""; }; - B55B5FA30F7659360064029C /* GHUnit */ = { - isa = PBXGroup; - children = ( - B55B5FAA0F76594D0064029C /* Classes */, - B55B5FBE0F76594D0064029C /* Libraries */, - B55B5FD10F76594D0064029C /* Classes-MacOSX */, - ); - name = GHUnit; - sourceTree = ""; - }; - B55B5FAA0F76594D0064029C /* Classes */ = { - isa = PBXGroup; - children = ( - B55B5FAB0F76594D0064029C /* GHTest.h */, - B55B5FAC0F76594D0064029C /* GHTest.m */, - B55B5FAD0F76594D0064029C /* GHTestCase.h */, - B55B5FAE0F76594D0064029C /* GHTestCase.m */, - B55B5FAF0F76594D0064029C /* GHTestGroup.h */, - B55B5FB00F76594D0064029C /* GHTestGroup.m */, - B55B5FB10F76594D0064029C /* GHTestMacros.h */, - B55B5FB20F76594D0064029C /* GHTestMacros.m */, - B55B5FB30F76594D0064029C /* GHTestRunner.h */, - B55B5FB40F76594D0064029C /* GHTestRunner.m */, - B55B5FB50F76594D0064029C /* GHTestSuite.h */, - B55B5FB60F76594D0064029C /* GHTestSuite.m */, - B55B5FB70F76594D0064029C /* GHTestUtils.h */, - B55B5FB80F76594D0064029C /* GHTestUtils.m */, - B55B5FB90F76594D0064029C /* GHUnit.h */, - B55B5FBA0F76594D0064029C /* RunTests.sh */, - B55B5FBB0F76594D0064029C /* SharedUI */, - ); - name = Classes; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Classes"; - sourceTree = SOURCE_ROOT; - }; - B55B5FBB0F76594D0064029C /* SharedUI */ = { - isa = PBXGroup; - children = ( - B55B5FBC0F76594D0064029C /* GHTestViewModel.h */, - B55B5FBD0F76594D0064029C /* GHTestViewModel.m */, - ); - path = SharedUI; - sourceTree = ""; - }; - B55B5FBE0F76594D0064029C /* Libraries */ = { - isa = PBXGroup; - children = ( - B55B5FBF0F76594D0064029C /* GHKit */, - B55B5FC60F76594D0064029C /* GTM */, - B55B5FD00F76594D0064029C /* README.md */, - ); - name = Libraries; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Libraries"; - sourceTree = SOURCE_ROOT; - }; - B55B5FBF0F76594D0064029C /* GHKit */ = { - isa = PBXGroup; - children = ( - B55B5FC00F76594D0064029C /* GHLogger.h */, - B55B5FC10F76594D0064029C /* GHLogger.m */, - B55B5FC20F76594D0064029C /* GHNSInvocation+Utils.h */, - B55B5FC30F76594D0064029C /* GHNSInvocation+Utils.m */, - B55B5FC40F76594D0064029C /* GHNSObject+Invocation.h */, - B55B5FC50F76594D0064029C /* GHNSObject+Invocation.m */, - ); - path = GHKit; - sourceTree = ""; - }; - B55B5FC60F76594D0064029C /* GTM */ = { - isa = PBXGroup; - children = ( - B55B5FC70F76594D0064029C /* Foundation */, - B55B5FCF0F76594D0064029C /* GTMDefines.h */, - ); - path = GTM; - sourceTree = ""; - }; - B55B5FC70F76594D0064029C /* Foundation */ = { - isa = PBXGroup; - children = ( - B55B5FC80F76594D0064029C /* GTMGarbageCollection.h */, - B55B5FC90F76594D0064029C /* GTMLogger.h */, - B55B5FCA0F76594D0064029C /* GTMLogger.m */, - B55B5FCB0F76594D0064029C /* GTMObjC2Runtime.h */, - B55B5FCC0F76594D0064029C /* GTMObjC2Runtime.m */, - B55B5FCD0F76594D0064029C /* GTMStackTrace.h */, - B55B5FCE0F76594D0064029C /* GTMStackTrace.m */, - ); - path = Foundation; - sourceTree = ""; - }; - B55B5FD10F76594D0064029C /* Classes-MacOSX */ = { - isa = PBXGroup; - children = ( - B55B5FD20F76594D0064029C /* GHUnitTestMain.m */, - B55B5FD30F76594D0064029C /* UI */, - ); - name = "Classes-MacOSX"; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Classes-MacOSX"; - sourceTree = SOURCE_ROOT; - }; - B55B5FD30F76594D0064029C /* UI */ = { - isa = PBXGroup; - children = ( - B55B5FD40F76594D0064029C /* GHTestApp.h */, - B55B5FD50F76594D0064029C /* GHTestApp.m */, - B55B5FD60F76594D0064029C /* GHTestApp.xib */, - B55B5FD70F76594D0064029C /* GHTestAppDelegate.h */, - B55B5FD80F76594D0064029C /* GHTestAppDelegate.m */, - B55B5FD90F76594D0064029C /* GHTestView.xib */, - B55B5FDA0F76594D0064029C /* GHTestViewController.h */, - B55B5FDB0F76594D0064029C /* GHTestViewController.m */, - B55B5FDC0F76594D0064029C /* GHTestWindow.xib */, - B55B5FDD0F76594D0064029C /* GHTestWindowController.h */, - B55B5FDE0F76594D0064029C /* GHTestWindowController.m */, - ); - path = UI; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -396,6 +228,7 @@ B55B5EDB0F7658C70064029C /* Resources */, B55B5EDC0F7658C70064029C /* Sources */, B55B5EDD0F7658C70064029C /* Frameworks */, + B5B513820FBEE477002C74D0 /* CopyFiles */, ); buildRules = ( ); @@ -437,11 +270,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B55B5FEF0F76594D0064029C /* RunTests.sh in Resources */, - B55B5FF70F76594D0064029C /* README.md in Resources */, - B55B5FFA0F76594D0064029C /* GHTestApp.xib in Resources */, - B55B5FFC0F76594D0064029C /* GHTestView.xib in Resources */, - B55B5FFE0F76594D0064029C /* GHTestWindow.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -465,25 +293,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - B55B5FE80F76594D0064029C /* GHTest.m in Sources */, - B55B5FE90F76594D0064029C /* GHTestCase.m in Sources */, - B55B5FEA0F76594D0064029C /* GHTestGroup.m in Sources */, - B55B5FEB0F76594D0064029C /* GHTestMacros.m in Sources */, - B55B5FEC0F76594D0064029C /* GHTestRunner.m in Sources */, - B55B5FED0F76594D0064029C /* GHTestSuite.m in Sources */, - B55B5FEE0F76594D0064029C /* GHTestUtils.m in Sources */, - B55B5FF00F76594D0064029C /* GHTestViewModel.m in Sources */, - B55B5FF10F76594D0064029C /* GHLogger.m in Sources */, - B55B5FF20F76594D0064029C /* GHNSInvocation+Utils.m in Sources */, - B55B5FF30F76594D0064029C /* GHNSObject+Invocation.m in Sources */, - B55B5FF40F76594D0064029C /* GTMLogger.m in Sources */, - B55B5FF50F76594D0064029C /* GTMObjC2Runtime.m in Sources */, - B55B5FF60F76594D0064029C /* GTMStackTrace.m in Sources */, - B55B5FF80F76594D0064029C /* GHUnitTestMain.m in Sources */, - B55B5FF90F76594D0064029C /* GHTestApp.m in Sources */, - B55B5FFB0F76594D0064029C /* GHTestAppDelegate.m in Sources */, - B55B5FFD0F76594D0064029C /* GHTestViewController.m in Sources */, - B55B5FFF0F76594D0064029C /* GHTestWindowController.m in Sources */, B55B60080F7659790064029C /* ASIFormDataRequestTests.m in Sources */, B55B60090F76597C0064029C /* ASIHTTPRequestTests.m in Sources */, B55B600A0F7659800064029C /* ASINetworkQueueTests.m in Sources */, @@ -491,6 +300,7 @@ B55B600E0F76598D0064029C /* NSHTTPCookieAdditions.m in Sources */, B55B600F0F7659900064029C /* ASIHTTPRequest.m in Sources */, B55B60100F7659960064029C /* ASIFormDataRequest.m in Sources */, + B5B513860FBEE515002C74D0 /* GHUnitTestMain.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -521,6 +331,11 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = NO; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/GHUnit\"", + "\"$(SRCROOT)/Frameworks\"", + ); GCC_DYNAMIC_NO_PIC = NO; GCC_ENABLE_FIX_AND_CONTINUE = YES; GCC_MODEL_TUNING = G5; @@ -529,6 +344,7 @@ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/AppKit.framework/Headers/AppKit.h"; INFOPLIST_FILE = "Mac Sample/Tests-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LD_RUNPATH_SEARCH_PATHS = "@loader_path/../Frameworks"; OTHER_LDFLAGS = ( "-framework", Foundation, @@ -546,6 +362,11 @@ ALWAYS_SEARCH_USER_PATHS = NO; COPY_PHASE_STRIP = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Classes/GHUnit\"", + "\"$(SRCROOT)/Frameworks\"", + ); GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_MODEL_TUNING = G5; GCC_PRECOMPILE_PREFIX_HEADER = YES; diff --git a/iPhone.xcodeproj/project.pbxproj b/iPhone.xcodeproj/project.pbxproj index 38e541b0..e9f560d9 100644 --- a/iPhone.xcodeproj/project.pbxproj +++ b/iPhone.xcodeproj/project.pbxproj @@ -33,32 +33,13 @@ B55B60D30F765BC90064029C /* ASIFormDataRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60530F765A3C0064029C /* ASIFormDataRequestTests.m */; }; B55B60D40F765BCD0064029C /* ASIHTTPRequestTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60550F765A3C0064029C /* ASIHTTPRequestTests.m */; }; B55B60D50F765BD00064029C /* ASINetworkQueueTests.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60570F765A3C0064029C /* ASINetworkQueueTests.m */; }; - B55B610C0F765BE80064029C /* GHTest.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60D90F765BE80064029C /* GHTest.m */; }; - B55B610D0F765BE80064029C /* GHTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60DB0F765BE80064029C /* GHTestCase.m */; }; - B55B610E0F765BE80064029C /* GHTestGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60DD0F765BE80064029C /* GHTestGroup.m */; }; - B55B610F0F765BE80064029C /* GHTestMacros.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60DF0F765BE80064029C /* GHTestMacros.m */; }; - B55B61100F765BE80064029C /* GHTestRunner.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60E10F765BE80064029C /* GHTestRunner.m */; }; - B55B61110F765BE80064029C /* GHTestSuite.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60E30F765BE80064029C /* GHTestSuite.m */; }; - B55B61120F765BE80064029C /* GHTestUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60E50F765BE80064029C /* GHTestUtils.m */; }; - B55B61130F765BE80064029C /* RunTests.sh in Resources */ = {isa = PBXBuildFile; fileRef = B55B60E70F765BE80064029C /* RunTests.sh */; }; - B55B61140F765BE80064029C /* GHTestViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60EA0F765BE80064029C /* GHTestViewModel.m */; }; - B55B61150F765BE80064029C /* GHLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60EE0F765BE80064029C /* GHLogger.m */; }; - B55B61160F765BE80064029C /* GHNSInvocation+Utils.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60F00F765BE80064029C /* GHNSInvocation+Utils.m */; }; - B55B61170F765BE80064029C /* GHNSObject+Invocation.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60F20F765BE80064029C /* GHNSObject+Invocation.m */; }; - B55B61180F765BE80064029C /* GTMLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60F70F765BE80064029C /* GTMLogger.m */; }; - B55B61190F765BE80064029C /* GTMObjC2Runtime.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60F90F765BE80064029C /* GTMObjC2Runtime.m */; }; - B55B611A0F765BE80064029C /* GTMStackTrace.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B60FB0F765BE80064029C /* GTMStackTrace.m */; }; - B55B611B0F765BE80064029C /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = B55B60FD0F765BE80064029C /* README.md */; }; - B55B612E0F765BF80064029C /* GHUnitIPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = B55B61260F765BF80064029C /* GHUnitIPhone.xib */; }; - B55B612F0F765BF80064029C /* GHUnitIPhoneAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B61280F765BF80064029C /* GHUnitIPhoneAppDelegate.m */; }; - B55B61300F765BF80064029C /* GHUnitIPhoneExceptionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B612A0F765BF80064029C /* GHUnitIPhoneExceptionViewController.m */; }; - B55B61310F765BF80064029C /* GHUnitIPhoneTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B612B0F765BF80064029C /* GHUnitIPhoneTestMain.m */; }; - B55B61320F765BF80064029C /* GHUnitIPhoneViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = B55B612D0F765BF80064029C /* GHUnitIPhoneViewController.m */; }; B55B61360F765C130064029C /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B55B60920F765AF50064029C /* CFNetwork.framework */; }; B55B61370F765C170064029C /* libz.1.2.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = B55B60940F765AF80064029C /* libz.1.2.3.dylib */; }; B55B613C0F765C240064029C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765070DF74369002DB57D /* CoreGraphics.framework */; }; B55B615B0F765C720064029C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; B55B616A0F765CA40064029C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; + B5B513CE0FBEE622002C74D0 /* GHUnitIPhoneTestMain.m in Sources */ = {isa = PBXBuildFile; fileRef = B5B513C20FBEE622002C74D0 /* GHUnitIPhoneTestMain.m */; }; + B5B513CF0FBEE622002C74D0 /* libGHUnitIPhone.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B5B513C80FBEE622002C74D0 /* libGHUnitIPhone.a */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -100,47 +81,21 @@ B55B60940F765AF80064029C /* libz.1.2.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.1.2.3.dylib; path = usr/lib/libz.1.2.3.dylib; sourceTree = SDKROOT; }; B55B60C70F765BB00064029C /* Unit Tests (GHUnit).app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Unit Tests (GHUnit).app"; sourceTree = BUILT_PRODUCTS_DIR; }; B55B60CB0F765BB10064029C /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "Tests-Info.plist"; path = "iPhone Sample/Tests-Info.plist"; sourceTree = ""; }; - B55B60D80F765BE80064029C /* GHTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTest.h; sourceTree = ""; }; - B55B60D90F765BE80064029C /* GHTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTest.m; sourceTree = ""; }; - B55B60DA0F765BE80064029C /* GHTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestCase.h; sourceTree = ""; }; - B55B60DB0F765BE80064029C /* GHTestCase.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestCase.m; sourceTree = ""; }; - B55B60DC0F765BE80064029C /* GHTestGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestGroup.h; sourceTree = ""; }; - B55B60DD0F765BE80064029C /* GHTestGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestGroup.m; sourceTree = ""; }; - B55B60DE0F765BE80064029C /* GHTestMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestMacros.h; sourceTree = ""; }; - B55B60DF0F765BE80064029C /* GHTestMacros.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestMacros.m; sourceTree = ""; }; - B55B60E00F765BE80064029C /* GHTestRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestRunner.h; sourceTree = ""; }; - B55B60E10F765BE80064029C /* GHTestRunner.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestRunner.m; sourceTree = ""; }; - B55B60E20F765BE80064029C /* GHTestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestSuite.h; sourceTree = ""; }; - B55B60E30F765BE80064029C /* GHTestSuite.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestSuite.m; sourceTree = ""; }; - B55B60E40F765BE80064029C /* GHTestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestUtils.h; sourceTree = ""; }; - B55B60E50F765BE80064029C /* GHTestUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestUtils.m; sourceTree = ""; }; - B55B60E60F765BE80064029C /* GHUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHUnit.h; sourceTree = ""; }; - B55B60E70F765BE80064029C /* RunTests.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = RunTests.sh; sourceTree = ""; }; - B55B60E90F765BE80064029C /* GHTestViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHTestViewModel.h; sourceTree = ""; }; - B55B60EA0F765BE80064029C /* GHTestViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHTestViewModel.m; sourceTree = ""; }; - B55B60ED0F765BE80064029C /* GHLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHLogger.h; sourceTree = ""; }; - B55B60EE0F765BE80064029C /* GHLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHLogger.m; sourceTree = ""; }; - B55B60EF0F765BE80064029C /* GHNSInvocation+Utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GHNSInvocation+Utils.h"; sourceTree = ""; }; - B55B60F00F765BE80064029C /* GHNSInvocation+Utils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GHNSInvocation+Utils.m"; sourceTree = ""; }; - B55B60F10F765BE80064029C /* GHNSObject+Invocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GHNSObject+Invocation.h"; sourceTree = ""; }; - B55B60F20F765BE80064029C /* GHNSObject+Invocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GHNSObject+Invocation.m"; sourceTree = ""; }; - B55B60F50F765BE80064029C /* GTMGarbageCollection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMGarbageCollection.h; sourceTree = ""; }; - B55B60F60F765BE80064029C /* GTMLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMLogger.h; sourceTree = ""; }; - B55B60F70F765BE80064029C /* GTMLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMLogger.m; sourceTree = ""; }; - B55B60F80F765BE80064029C /* GTMObjC2Runtime.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMObjC2Runtime.h; sourceTree = ""; }; - B55B60F90F765BE80064029C /* GTMObjC2Runtime.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMObjC2Runtime.m; sourceTree = ""; }; - B55B60FA0F765BE80064029C /* GTMStackTrace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMStackTrace.h; sourceTree = ""; }; - B55B60FB0F765BE80064029C /* GTMStackTrace.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GTMStackTrace.m; sourceTree = ""; }; - B55B60FC0F765BE80064029C /* GTMDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GTMDefines.h; sourceTree = ""; }; - B55B60FD0F765BE80064029C /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.md; sourceTree = ""; }; - B55B61260F765BF80064029C /* GHUnitIPhone.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GHUnitIPhone.xib; sourceTree = ""; }; - B55B61270F765BF80064029C /* GHUnitIPhoneAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHUnitIPhoneAppDelegate.h; sourceTree = ""; }; - B55B61280F765BF80064029C /* GHUnitIPhoneAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitIPhoneAppDelegate.m; sourceTree = ""; }; - B55B61290F765BF80064029C /* GHUnitIPhoneExceptionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHUnitIPhoneExceptionViewController.h; sourceTree = ""; }; - B55B612A0F765BF80064029C /* GHUnitIPhoneExceptionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitIPhoneExceptionViewController.m; sourceTree = ""; }; - B55B612B0F765BF80064029C /* GHUnitIPhoneTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitIPhoneTestMain.m; sourceTree = ""; }; - B55B612C0F765BF80064029C /* GHUnitIPhoneViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GHUnitIPhoneViewController.h; sourceTree = ""; }; - B55B612D0F765BF80064029C /* GHUnitIPhoneViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GHUnitIPhoneViewController.m; sourceTree = ""; }; + B5B513BF0FBEE622002C74D0 /* GHTest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTest.h; path = Frameworks/libGHUnitIPhone/GHTest.h; sourceTree = SOURCE_ROOT; }; + B5B513C00FBEE622002C74D0 /* GHUnit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHUnit.h; path = Frameworks/libGHUnitIPhone/GHUnit.h; sourceTree = SOURCE_ROOT; }; + B5B513C10FBEE622002C74D0 /* GHMockNSHTTPURLResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHMockNSHTTPURLResponse.h; path = Frameworks/libGHUnitIPhone/GHMockNSHTTPURLResponse.h; sourceTree = SOURCE_ROOT; }; + B5B513C20FBEE622002C74D0 /* GHUnitIPhoneTestMain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = GHUnitIPhoneTestMain.m; path = Frameworks/libGHUnitIPhone/GHUnitIPhoneTestMain.m; sourceTree = SOURCE_ROOT; }; + B5B513C30FBEE622002C74D0 /* GHTestSuite.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTestSuite.h; path = Frameworks/libGHUnitIPhone/GHTestSuite.h; sourceTree = SOURCE_ROOT; }; + B5B513C40FBEE622002C74D0 /* GHTesting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTesting.h; path = Frameworks/libGHUnitIPhone/GHTesting.h; sourceTree = SOURCE_ROOT; }; + B5B513C50FBEE622002C74D0 /* GHUNSObject+Swizzle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GHUNSObject+Swizzle.h"; path = "Frameworks/libGHUnitIPhone/GHUNSObject+Swizzle.h"; sourceTree = SOURCE_ROOT; }; + B5B513C60FBEE622002C74D0 /* GHMockNSURLConnection.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHMockNSURLConnection.h; path = Frameworks/libGHUnitIPhone/GHMockNSURLConnection.h; sourceTree = SOURCE_ROOT; }; + B5B513C70FBEE622002C74D0 /* GHTestRunner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTestRunner.h; path = Frameworks/libGHUnitIPhone/GHTestRunner.h; sourceTree = SOURCE_ROOT; }; + B5B513C80FBEE622002C74D0 /* libGHUnitIPhone.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libGHUnitIPhone.a; path = Frameworks/libGHUnitIPhone/libGHUnitIPhone.a; sourceTree = SOURCE_ROOT; }; + B5B513C90FBEE622002C74D0 /* GHNSLocale+Mock.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "GHNSLocale+Mock.h"; path = "Frameworks/libGHUnitIPhone/GHNSLocale+Mock.h"; sourceTree = SOURCE_ROOT; }; + B5B513CA0FBEE622002C74D0 /* GHTestMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTestMacros.h; path = Frameworks/libGHUnitIPhone/GHTestMacros.h; sourceTree = SOURCE_ROOT; }; + B5B513CB0FBEE622002C74D0 /* GHTestGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTestGroup.h; path = Frameworks/libGHUnitIPhone/GHTestGroup.h; sourceTree = SOURCE_ROOT; }; + B5B513CC0FBEE622002C74D0 /* GHTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHTestCase.h; path = Frameworks/libGHUnitIPhone/GHTestCase.h; sourceTree = SOURCE_ROOT; }; + B5B513CD0FBEE622002C74D0 /* GHAsyncTestCase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GHAsyncTestCase.h; path = Frameworks/libGHUnitIPhone/GHAsyncTestCase.h; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -165,6 +120,7 @@ B55B613C0F765C240064029C /* CoreGraphics.framework in Frameworks */, B55B615B0F765C720064029C /* UIKit.framework in Frameworks */, B55B616A0F765CA40064029C /* Foundation.framework in Frameworks */, + B5B513CF0FBEE622002C74D0 /* libGHUnitIPhone.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -174,7 +130,7 @@ 080E96DDFE201D6D7F000001 /* Classes */ = { isa = PBXGroup; children = ( - B55B60D60F765BE80064029C /* GHUnit */, + B5B513BE0FBEE602002C74D0 /* GHUnit */, B55B60450F765A320064029C /* ASIFormDataRequest.h */, B55B60460F765A320064029C /* ASIFormDataRequest.m */, B55B60470F765A320064029C /* ASIHTTPRequest.h */, @@ -265,113 +221,28 @@ path = Tests; sourceTree = ""; }; - B55B60D60F765BE80064029C /* GHUnit */ = { + B5B513BE0FBEE602002C74D0 /* GHUnit */ = { isa = PBXGroup; children = ( - B55B60D70F765BE80064029C /* Classes */, - B55B60EB0F765BE80064029C /* Libraries */, - B55B61250F765BF80064029C /* Classes-IPhone */, + B5B513BF0FBEE622002C74D0 /* GHTest.h */, + B5B513C00FBEE622002C74D0 /* GHUnit.h */, + B5B513C10FBEE622002C74D0 /* GHMockNSHTTPURLResponse.h */, + B5B513C20FBEE622002C74D0 /* GHUnitIPhoneTestMain.m */, + B5B513C30FBEE622002C74D0 /* GHTestSuite.h */, + B5B513C40FBEE622002C74D0 /* GHTesting.h */, + B5B513C50FBEE622002C74D0 /* GHUNSObject+Swizzle.h */, + B5B513C60FBEE622002C74D0 /* GHMockNSURLConnection.h */, + B5B513C70FBEE622002C74D0 /* GHTestRunner.h */, + B5B513C80FBEE622002C74D0 /* libGHUnitIPhone.a */, + B5B513C90FBEE622002C74D0 /* GHNSLocale+Mock.h */, + B5B513CA0FBEE622002C74D0 /* GHTestMacros.h */, + B5B513CB0FBEE622002C74D0 /* GHTestGroup.h */, + B5B513CC0FBEE622002C74D0 /* GHTestCase.h */, + B5B513CD0FBEE622002C74D0 /* GHAsyncTestCase.h */, ); name = GHUnit; sourceTree = ""; }; - B55B60D70F765BE80064029C /* Classes */ = { - isa = PBXGroup; - children = ( - B55B60D80F765BE80064029C /* GHTest.h */, - B55B60D90F765BE80064029C /* GHTest.m */, - B55B60DA0F765BE80064029C /* GHTestCase.h */, - B55B60DB0F765BE80064029C /* GHTestCase.m */, - B55B60DC0F765BE80064029C /* GHTestGroup.h */, - B55B60DD0F765BE80064029C /* GHTestGroup.m */, - B55B60DE0F765BE80064029C /* GHTestMacros.h */, - B55B60DF0F765BE80064029C /* GHTestMacros.m */, - B55B60E00F765BE80064029C /* GHTestRunner.h */, - B55B60E10F765BE80064029C /* GHTestRunner.m */, - B55B60E20F765BE80064029C /* GHTestSuite.h */, - B55B60E30F765BE80064029C /* GHTestSuite.m */, - B55B60E40F765BE80064029C /* GHTestUtils.h */, - B55B60E50F765BE80064029C /* GHTestUtils.m */, - B55B60E60F765BE80064029C /* GHUnit.h */, - B55B60E70F765BE80064029C /* RunTests.sh */, - B55B60E80F765BE80064029C /* SharedUI */, - ); - name = Classes; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Classes"; - sourceTree = SOURCE_ROOT; - }; - B55B60E80F765BE80064029C /* SharedUI */ = { - isa = PBXGroup; - children = ( - B55B60E90F765BE80064029C /* GHTestViewModel.h */, - B55B60EA0F765BE80064029C /* GHTestViewModel.m */, - ); - path = SharedUI; - sourceTree = ""; - }; - B55B60EB0F765BE80064029C /* Libraries */ = { - isa = PBXGroup; - children = ( - B55B60EC0F765BE80064029C /* GHKit */, - B55B60F30F765BE80064029C /* GTM */, - B55B60FD0F765BE80064029C /* README.md */, - ); - name = Libraries; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Libraries"; - sourceTree = SOURCE_ROOT; - }; - B55B60EC0F765BE80064029C /* GHKit */ = { - isa = PBXGroup; - children = ( - B55B60ED0F765BE80064029C /* GHLogger.h */, - B55B60EE0F765BE80064029C /* GHLogger.m */, - B55B60EF0F765BE80064029C /* GHNSInvocation+Utils.h */, - B55B60F00F765BE80064029C /* GHNSInvocation+Utils.m */, - B55B60F10F765BE80064029C /* GHNSObject+Invocation.h */, - B55B60F20F765BE80064029C /* GHNSObject+Invocation.m */, - ); - path = GHKit; - sourceTree = ""; - }; - B55B60F30F765BE80064029C /* GTM */ = { - isa = PBXGroup; - children = ( - B55B60F40F765BE80064029C /* Foundation */, - B55B60FC0F765BE80064029C /* GTMDefines.h */, - ); - path = GTM; - sourceTree = ""; - }; - B55B60F40F765BE80064029C /* Foundation */ = { - isa = PBXGroup; - children = ( - B55B60F50F765BE80064029C /* GTMGarbageCollection.h */, - B55B60F60F765BE80064029C /* GTMLogger.h */, - B55B60F70F765BE80064029C /* GTMLogger.m */, - B55B60F80F765BE80064029C /* GTMObjC2Runtime.h */, - B55B60F90F765BE80064029C /* GTMObjC2Runtime.m */, - B55B60FA0F765BE80064029C /* GTMStackTrace.h */, - B55B60FB0F765BE80064029C /* GTMStackTrace.m */, - ); - path = Foundation; - sourceTree = ""; - }; - B55B61250F765BF80064029C /* Classes-IPhone */ = { - isa = PBXGroup; - children = ( - B55B61260F765BF80064029C /* GHUnitIPhone.xib */, - B55B61270F765BF80064029C /* GHUnitIPhoneAppDelegate.h */, - B55B61280F765BF80064029C /* GHUnitIPhoneAppDelegate.m */, - B55B61290F765BF80064029C /* GHUnitIPhoneExceptionViewController.h */, - B55B612A0F765BF80064029C /* GHUnitIPhoneExceptionViewController.m */, - B55B612B0F765BF80064029C /* GHUnitIPhoneTestMain.m */, - B55B612C0F765BF80064029C /* GHUnitIPhoneViewController.h */, - B55B612D0F765BF80064029C /* GHUnitIPhoneViewController.m */, - ); - name = "Classes-IPhone"; - path = "../Downloads/gabriel-gh-unit-02ab4e28177c2b63a9aaddafbd9b43a5c53f042b/Classes-IPhone"; - sourceTree = SOURCE_ROOT; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -444,9 +315,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - B55B61130F765BE80064029C /* RunTests.sh in Resources */, - B55B611B0F765BE80064029C /* README.md in Resources */, - B55B612E0F765BF80064029C /* GHUnitIPhone.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -480,24 +348,7 @@ B55B60D30F765BC90064029C /* ASIFormDataRequestTests.m in Sources */, B55B60D40F765BCD0064029C /* ASIHTTPRequestTests.m in Sources */, B55B60D50F765BD00064029C /* ASINetworkQueueTests.m in Sources */, - B55B610C0F765BE80064029C /* GHTest.m in Sources */, - B55B610D0F765BE80064029C /* GHTestCase.m in Sources */, - B55B610E0F765BE80064029C /* GHTestGroup.m in Sources */, - B55B610F0F765BE80064029C /* GHTestMacros.m in Sources */, - B55B61100F765BE80064029C /* GHTestRunner.m in Sources */, - B55B61110F765BE80064029C /* GHTestSuite.m in Sources */, - B55B61120F765BE80064029C /* GHTestUtils.m in Sources */, - B55B61140F765BE80064029C /* GHTestViewModel.m in Sources */, - B55B61150F765BE80064029C /* GHLogger.m in Sources */, - B55B61160F765BE80064029C /* GHNSInvocation+Utils.m in Sources */, - B55B61170F765BE80064029C /* GHNSObject+Invocation.m in Sources */, - B55B61180F765BE80064029C /* GTMLogger.m in Sources */, - B55B61190F765BE80064029C /* GTMObjC2Runtime.m in Sources */, - B55B611A0F765BE80064029C /* GTMStackTrace.m in Sources */, - B55B612F0F765BF80064029C /* GHUnitIPhoneAppDelegate.m in Sources */, - B55B61300F765BF80064029C /* GHUnitIPhoneExceptionViewController.m in Sources */, - B55B61310F765BF80064029C /* GHUnitIPhoneTestMain.m in Sources */, - B55B61320F765BF80064029C /* GHUnitIPhoneViewController.m in Sources */, + B5B513CE0FBEE622002C74D0 /* GHUnitIPhoneTestMain.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -548,11 +399,16 @@ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/UIKit.framework/Headers/UIKit.h"; INFOPLIST_FILE = "iPhone Sample/Tests-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Frameworks/libGHUnitIPhone\"", + ); OTHER_LDFLAGS = ( "-framework", Foundation, "-framework", UIKit, + "-ObjC", ); PREBINDING = NO; PRODUCT_NAME = "Unit Tests (GHUnit)"; @@ -572,6 +428,10 @@ GCC_PREFIX_HEADER = "$(SYSTEM_LIBRARY_DIR)/Frameworks/UIKit.framework/Headers/UIKit.h"; INFOPLIST_FILE = "iPhone Sample/Tests-Info.plist"; INSTALL_PATH = "$(HOME)/Applications"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "\"$(SRCROOT)/Frameworks/libGHUnitIPhone\"", + ); OTHER_LDFLAGS = ( "-framework", Foundation,