| @@ -0,0 +1,173 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| 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 waitForStatus: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 to connection delegate. | ||
| @param data Data to send | ||
| @param statusCode HTTP status code | ||
| @param MIMEType Mime type | ||
| @param afterDelay Delay | ||
| */ | ||
| - (void)receiveData:(NSData *)data statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType 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 Path to load data 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; | ||
|
|
||
| /*! | ||
| Sends mock response, sends data, and then calls finish. | ||
| (For asynchronous requests) | ||
| @param data Data to load. 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)receiveData:(NSData *)data statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType afterDelay:(NSTimeInterval)delay; | ||
|
|
||
| /*! | ||
| Calls connection:didFailWithError: on delegate after specified delay. | ||
| @param error The error to pass to the delegate. | ||
| @param delay Delay before responding (if < 0, there is no delay) | ||
| */ | ||
| - (void)failWithError:(NSError *)error afterDelay:(NSTimeInterval)delay; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,132 @@ | ||
| // | ||
| // GHNSInvocation+Utils.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 <Foundation/Foundation.h> | ||
|
|
||
| // | ||
| // Creates arguments NSArray from var args, with first object named 'object' | ||
| // - (void)methodName:(id)arg1 withObjects:object, ... | ||
| // | ||
| #define GHConvertVarArgs(object) \ | ||
| NSMutableArray *arguments = [NSMutableArray array]; \ | ||
| do { \ | ||
| id arg; \ | ||
| va_list args; \ | ||
| if (object) { \ | ||
| [arguments addObject:object]; \ | ||
| va_start(args, object); \ | ||
| while ((arg = va_arg(args, id))) \ | ||
| [arguments addObject:arg]; \ | ||
| va_end(args); \ | ||
| } \ | ||
| } while(0); | ||
|
|
||
| @interface NSInvocation (GHUtils_GHUNIT) | ||
|
|
||
| /*! | ||
| Invoke on main thread. | ||
| @param waitUntilDone Whether to join on the call | ||
| */ | ||
| - (void)ghu_invokeOnMainThread:(BOOL)waitUntilDone; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param withObjects (Variable) Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param arguments Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param afterDelay Time interval for delay (in seconds) | ||
| @param arguments Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector afterDelay:(NSTimeInterval)delay arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param withObjects Nil terminated list of (object) arguments; Use [NSNull null] for nil arguments | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param arguments Arguments list | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param afterDelay Time interval for delay (in seconds) | ||
| @param arguments Arguments list | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone afterDelay:(NSTimeInterval)delay arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Create invocation with variable arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param hasReturnValue Will be set to YES, if there is a return value | ||
| @param withObjects (Variable) Arguments list | ||
| */ | ||
| + (NSInvocation *)ghu_invocationWithTarget:(id)target selector:(SEL)selector hasReturnValue:(BOOL *)hasReturnValue withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Create invocation with variable arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param hasReturnValue Will be set to YES, if there is a return value | ||
| @param arguments Arguments array | ||
| */ | ||
| + (NSInvocation *)ghu_invocationWithTarget:target selector:(SEL)selector hasReturnValue:(BOOL *)hasReturnValue arguments:(NSArray *)arguments; | ||
|
|
||
| @end |
| @@ -0,0 +1,133 @@ | ||
| // | ||
| // GHNSInvocationProxy_GHUNIT.h | ||
| // GHKit | ||
| // | ||
| // Modified by Gabriel Handford on 5/9/09. | ||
| // This class is based on DDInvocationGrabber. | ||
| // | ||
|
|
||
| /* | ||
| * Copyright (c) 2007-2009 Dave Dribin | ||
| * | ||
| * 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. | ||
| */ | ||
|
|
||
|
|
||
| /* | ||
| * This class is based on CInvocationGrabber: | ||
| * | ||
| * Copyright (c) 2007, Toxic Software | ||
| * All rights reserved. | ||
| * Redistribution and use in source and binary forms, with or without | ||
| * modification, are permitted provided that the following conditions are | ||
| * met: | ||
| * | ||
| * * Redistributions of source code must retain the above copyright notice, | ||
| * this list of conditions and the following disclaimer. | ||
| * | ||
| * * 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. | ||
| * | ||
| * * Neither the name of the Toxic Software nor the names of its | ||
| * contributors may be used to endorse or promote products derived from | ||
| * this software without specific prior written permission. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 THE REGENTS 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. | ||
| * | ||
| */ | ||
|
|
||
| /*! | ||
| Proxy that allows invocation on a separate thread, or with a delay. | ||
| Use with the GHNSObject+Invocation category: | ||
| @code | ||
| NSMutableArray *array = ...; | ||
| // Adds object to array after 5 seconds | ||
| [[array ghu_proxyAfterDelay:5.0] addObject:@"test"]; | ||
| NSThread *thread = ... | ||
| // Remove all objects from another thread | ||
| [[array ghu_proxyOnThread:thread waitUntilDone:NO] removeAllObjects]; | ||
| @endcode | ||
| Create invocation proxy for a NSMutableArray. | ||
| @code | ||
| NSMutableArray *array = ...; | ||
| NSThread *thread = ... | ||
| GHNSInvocationProxy_GHUNIT *arrayProxy = [GHNSInvocationProxy_GHUNIT invocation]; | ||
| arrayProxy.target = array; | ||
| arrayProxy.thread = thread; | ||
| arrayProxy.waitUntilDone = NO; | ||
| // Performs method on thread and doesn't wait for return | ||
| [arrayProxy addObject:@"test"]; | ||
| @endcode | ||
| */ | ||
| @interface GHNSInvocationProxy_GHUNIT : NSProxy { | ||
|
|
||
| id target_; | ||
|
|
||
| NSThread *thread_; | ||
| BOOL waitUntilDone_; | ||
| NSTimeInterval delay_; | ||
|
|
||
| // If debuging time to set | ||
| NSTimeInterval *time_; | ||
|
|
||
| NSInvocation *invocation_; | ||
| } | ||
|
|
||
| @property (retain, nonatomic) id target; | ||
| @property (retain, nonatomic) NSInvocation *invocation; | ||
| @property (retain, nonatomic) NSThread *thread; | ||
| @property (assign, nonatomic) BOOL waitUntilDone; | ||
| @property (assign, nonatomic) NSTimeInterval delay; | ||
| @property (assign, nonatomic) NSTimeInterval *time; | ||
|
|
||
| /*! | ||
| Create autoreleased empty invocation proxy. | ||
| @result Invocation proxy | ||
| */ | ||
| + (id)invocation; | ||
|
|
||
| /*! | ||
| Create invocation proxy with target. | ||
| @param target | ||
| @result Invocation proxy | ||
| */ | ||
| - (id)prepareWithInvocationTarget:(id)target; | ||
|
|
||
| @end |
| @@ -0,0 +1,63 @@ | ||
| // | ||
| // GHNSLocale+Mock.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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| /*! | ||
| 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 | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,100 @@ | ||
| // | ||
| // 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" | ||
| #import "GHNSInvocationProxy.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; | ||
|
|
||
|
|
||
| // Invocation proxies | ||
|
|
||
| - (id)ghu_proxyOnMainThread; | ||
| - (id)ghu_proxyOnMainThread:(BOOL)waitUntilDone; | ||
| - (id)ghu_proxyOnThread:(NSThread *)thread; | ||
| - (id)ghu_proxyOnThread:(NSThread *)thread waitUntilDone:(BOOL)waitUntilDone; | ||
| - (id)ghu_proxyAfterDelay:(NSTimeInterval)delay; | ||
|
|
||
| // Debug proxies | ||
| - (id)ghu_timedProxy:(NSTimeInterval *)time; | ||
| - (id)ghu_debugProxy:(NSTimeInterval *)time proxy:(GHNSInvocationProxy_GHUNIT **)proxy; | ||
|
|
||
| @end |
| @@ -0,0 +1,44 @@ | ||
| // | ||
| // GHTest+JUnitXML.h | ||
| // GHUnit | ||
| // | ||
| // Created by Gabriel Handford on 6/4/10. | ||
| // Copyright 2010. 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import "GHTest.h" | ||
|
|
||
| @interface GHTest(JUnitXML) | ||
|
|
||
| /*! | ||
| Return test results in JUnit XML format for external parsing use | ||
| (such as a Continuous Integration system like Hudson) | ||
| */ | ||
| - (NSString *)JUnitXML; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,184 @@ | ||
| // | ||
| // GHTest.h | ||
| // GHUnit | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| /*! | ||
| Test status. | ||
| */ | ||
| typedef enum { | ||
| GHTestStatusNone = 0, | ||
| GHTestStatusRunning, // Test is running | ||
| GHTestStatusCancelling, // Test is being cancelled | ||
| GHTestStatusCancelled, // Test was cancelled | ||
| GHTestStatusSucceeded, // Test finished and succeeded | ||
| GHTestStatusErrored, // Test finished and errored | ||
| } GHTestStatus; | ||
|
|
||
| enum { | ||
| GHTestOptionReraiseExceptions = 1 << 0, // Allows exceptions to be raised (so you can trigger the debugger) | ||
| GHTestOptionForceSetUpTearDownClass = 1 << 1, // Runs setUpClass/tearDownClass for this (each) test; Used when re-running a single test in a group | ||
| }; | ||
| typedef NSInteger GHTestOptions; | ||
|
|
||
| /*! | ||
| Generate string from GHTestStatus | ||
| @param status | ||
| */ | ||
| extern NSString* NSStringFromGHTestStatus(GHTestStatus status); | ||
|
|
||
| /*! | ||
| Check if test is running (or trying to cancel). | ||
| */ | ||
| extern BOOL GHTestStatusIsRunning(GHTestStatus status); | ||
|
|
||
| /*! | ||
| Check if test has succeeded, errored or cancelled. | ||
| */ | ||
| extern BOOL GHTestStatusEnded(GHTestStatus status); | ||
|
|
||
| /*! | ||
| Test stats. | ||
| */ | ||
| typedef struct { | ||
| NSInteger succeedCount; // Number of succeeded tests | ||
| NSInteger failureCount; // Number of failed tests | ||
| NSInteger cancelCount; // Number of aborted tests | ||
| NSInteger testCount; // Total number of tests | ||
| } GHTestStats; | ||
|
|
||
| /*! | ||
| Create GHTestStats. | ||
| */ | ||
| extern GHTestStats GHTestStatsMake(NSInteger succeedCount, NSInteger failureCount, NSInteger cancelCount, NSInteger testCount); | ||
|
|
||
| extern const GHTestStats GHTestStatsEmpty; | ||
|
|
||
| extern NSString *NSStringFromGHTestStats(GHTestStats stats); | ||
|
|
||
| @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 <NSObject, NSCoding, NSCopying> | ||
|
|
||
| - (void)run:(GHTestOptions)options; | ||
|
|
||
| @property (readonly, nonatomic) NSString *identifier; // Unique identifier for test | ||
| @property (readonly, nonatomic) NSString *name; | ||
| @property (assign, nonatomic) NSTimeInterval interval; | ||
| @property (assign, nonatomic) GHTestStatus status; | ||
| @property (readonly, nonatomic) GHTestStats stats; | ||
| @property (retain, nonatomic) NSException *exception; | ||
| @property (assign, nonatomic, getter=isDisabled) BOOL disabled; | ||
| @property (assign, nonatomic, getter=isHidden) BOOL hidden; | ||
| @property (assign, nonatomic) id<GHTestDelegate> delegate; // weak | ||
|
|
||
| - (NSArray *)log; | ||
|
|
||
| - (void)reset; | ||
| - (void)cancel; | ||
|
|
||
| - (NSInteger)disabledCount; | ||
|
|
||
| @end | ||
|
|
||
| /*! | ||
| Test delegate for notification when a test starts and ends. | ||
| */ | ||
| @protocol GHTestDelegate <NSObject> | ||
| - (void)testDidStart:(id<GHTest>)test source:(id<GHTest>)source; | ||
| - (void)testDidUpdate:(id<GHTest>)test source:(id<GHTest>)source; | ||
| - (void)testDidEnd:(id<GHTest>)test source:(id<GHTest>)source; | ||
| - (void)test:(id<GHTest>)test didLog:(NSString *)message source:(id<GHTest>)source; | ||
| @end | ||
|
|
||
| /*! | ||
| Delegate which is notified of log messages from inside GHTestCase. | ||
| */ | ||
| @protocol GHTestCaseLogWriter <NSObject> | ||
| - (void)log:(NSString *)message testCase:(id)testCase; | ||
| @end | ||
|
|
||
| /*! | ||
| Default test implementation with a target/selector pair. | ||
| - Tests a target and selector | ||
| - Notifies a test delegate | ||
| - Keeps track of status, running time and failures | ||
| - Stores any test specific logging | ||
| */ | ||
| @interface GHTest : NSObject <GHTest, GHTestCaseLogWriter> { | ||
|
|
||
| NSObject<GHTestDelegate> *delegate_; // weak | ||
|
|
||
| id target_; | ||
| SEL selector_; | ||
|
|
||
| NSString *identifier_; | ||
| NSString *name_; | ||
| GHTestStatus status_; | ||
| NSTimeInterval interval_; | ||
| BOOL disabled_; | ||
| BOOL hidden_; | ||
| NSException *exception_; // If failed | ||
|
|
||
| NSMutableArray *log_; | ||
|
|
||
| } | ||
|
|
||
| @property (readonly, nonatomic) id target; | ||
| @property (readonly, nonatomic) SEL selector; | ||
| @property (readonly, nonatomic) NSArray *log; | ||
|
|
||
| /*! | ||
| Create test with identifier, name. | ||
| @param identifier Unique identifier | ||
| @param name Name | ||
| */ | ||
| - (id)initWithIdentifier:(NSString *)identifier name:(NSString *)name; | ||
|
|
||
| /*! | ||
| 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; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,23 @@ | ||
| // | ||
| // GHTestApp.h | ||
| // GHUnit | ||
| // | ||
| // Created by Gabriel Handford on 1/20/09. | ||
| // Copyright 2009. All rights reserved. | ||
| // | ||
|
|
||
| #import "GHTestWindowController.h" | ||
|
|
||
| @interface GHTestApp : NSObject { | ||
| NSMutableArray *topLevelObjects_; | ||
|
|
||
| GHTestWindowController *windowController_; | ||
|
|
||
| GHTestSuite *suite_; | ||
| } | ||
|
|
||
| - (id)initWithSuite:(GHTestSuite *)suite; | ||
|
|
||
| - (void)runTests; | ||
|
|
||
| @end |
| @@ -0,0 +1,146 @@ | ||
| // | ||
| // 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, | ||
| @code | ||
| GHTestLog(@"Some debug info, %@", obj); | ||
| @endcode | ||
| */ | ||
| #define GHTestLog(...) [self log:[NSString stringWithFormat:__VA_ARGS__, nil]] | ||
|
|
||
| /*! | ||
| 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<GHTestCaseLogWriter> logWriter_; // weak | ||
|
|
||
| SEL currentSelector_; | ||
| } | ||
|
|
||
| //! The current test selector | ||
| @property (assign, nonatomic) SEL currentSelector; | ||
| @property (assign, nonatomic) id<GHTestCaseLogWriter> logWriter; | ||
|
|
||
| // 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; | ||
|
|
||
| /*! | ||
| Whether to run the tests on a separate thread. Override this method in your | ||
| test case to override the default. | ||
| Default is NO, tests are run on a separate thread by default. | ||
| @result If YES runs on the main thread | ||
| */ | ||
| - (BOOL)shouldRunOnMainThread; | ||
|
|
||
| //! 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 |
| @@ -0,0 +1,42 @@ | ||
| // | ||
| // GHTestGroup+JUnitXML.h | ||
| // GHUnit | ||
| // | ||
| // Created by Gabriel Handford on 6/4/10. | ||
| // Copyright 2010. 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import "GHTestGroup.h" | ||
|
|
||
| @interface GHTestGroup(JUnitXML) | ||
|
|
||
| - (NSString *)JUnitXML; | ||
|
|
||
| - (BOOL)writeJUnitXMLAtPath:(NSString *)documentsPath error:(NSError **)error; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,176 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #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 <GHTest> | ||
| - (NSString *)name; | ||
| - (id<GHTestGroup>)parent; | ||
| - (NSArray *)children; | ||
| @end | ||
|
|
||
| /*! | ||
| @brief A collection of tests (or test groups). | ||
| A test group is a collection of id<GHTest>, 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 <GHTestDelegate, GHTestGroup> { | ||
|
|
||
| NSObject<GHTestDelegate> *delegate_; // weak | ||
| id<GHTestGroup> parent_; // weak | ||
|
|
||
| NSMutableArray */*of id<GHTest>*/children_; | ||
|
|
||
| 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) | ||
|
|
||
| BOOL didSetUpClass_; | ||
|
|
||
| GHTestOptions options_; | ||
|
|
||
| // Set if test is created from initWithTestCase:delegate: | ||
| // Allows use to perform setUpClass and tearDownClass (once per test case run) | ||
| id testCase_; | ||
|
|
||
| NSException *exception_; // If exception happens in group setUpClass/tearDownClass | ||
| } | ||
|
|
||
| @property (readonly, nonatomic) NSArray */*of id<GHTest>*/children; | ||
| @property (assign, nonatomic) id<GHTestGroup> parent; | ||
| @property (readonly, nonatomic) id testCase; | ||
| @property (assign, nonatomic) GHTestOptions options; | ||
|
|
||
| /*! | ||
| 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<GHTestDelegate>)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 | ||
| */ | ||
| - (id)initWithTestCase:(id)testCase delegate:(id<GHTestDelegate>)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<GHTestDelegate>)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<GHTestDelegate>)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; | ||
|
|
||
| /*! | ||
| Add a test group to this test group. | ||
| @param testGroup Test group to add | ||
| */ | ||
| - (void)addTestGroup:(GHTestGroup *)testGroup; | ||
|
|
||
| /*! | ||
| Add tests to this group. | ||
| @param tests Tests to add | ||
| */ | ||
| - (void)addTests:(NSArray */*of id<GHTest>*/)tests; | ||
|
|
||
| /*! | ||
| Add test to this group. | ||
| @param test Test to add | ||
| */ | ||
| - (void)addTest:(id<GHTest>)test; | ||
|
|
||
| /*! | ||
| Whether the test group should run on the main thread. | ||
| Call passes to test case instance if enabled. | ||
| */ | ||
| - (BOOL)shouldRunOnMainThread; | ||
|
|
||
| /*! | ||
| @result YES if we have any enabled chilren, NO if all children have been disabled. | ||
| */ | ||
| - (BOOL)hasEnabledChildren; | ||
|
|
||
| /*! | ||
| Get list of failed tests. | ||
| @result Failed tests | ||
| */ | ||
| - (NSArray */*of id<GHTest>*/)failedTests; | ||
|
|
||
| /*! | ||
| Run in operation queue. | ||
| Tests from the group are added and will block until they have completed. | ||
| @param operationQueue If nil, then runs as is | ||
| @param options Options | ||
| */ | ||
| - (void)runInOperationQueue:(NSOperationQueue *)operationQueue options:(GHTestOptions)options; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,46 @@ | ||
| // | ||
| // GHTestOperation.h | ||
| // GHUnit | ||
| // | ||
| // Created by Gabriel Handford on 6/4/10. | ||
| // Copyright 2010. 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import "GHTest.h" | ||
|
|
||
| /*! | ||
| Test for running in the context of an NSOperationQueue. | ||
| */ | ||
| @interface GHTestOperation : NSOperation { | ||
| id<GHTest> test_; | ||
| GHTestOptions options_; | ||
| } | ||
|
|
||
| - (id)initWithTest:(id<GHTest>)test options:(GHTestOptions)options; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,31 @@ | ||
| // | ||
| // GHTestOutlineViewModel.h | ||
| // GHUnit | ||
| // | ||
| // Created by Gabriel Handford on 7/17/09. | ||
| // Copyright 2009. All rights reserved. | ||
| // | ||
|
|
||
| #import "GHTestViewModel.h" | ||
| @class GHTestOutlineViewModel; | ||
|
|
||
|
|
||
| @protocol GHTestOutlineViewModelDelegate <NSObject> | ||
| - (void)testOutlineViewModelDidChangeSelection:(GHTestOutlineViewModel *)testOutlineViewModel; | ||
| @end | ||
|
|
||
|
|
||
|
|
||
| @interface GHTestOutlineViewModel : GHTestViewModel | ||
| #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 // on lines like this to not confuse IB | ||
| <NSOutlineViewDelegate, NSOutlineViewDataSource> | ||
| #endif | ||
| { | ||
| id<GHTestOutlineViewModelDelegate> delegate_; // weak | ||
|
|
||
| NSButtonCell *editCell_; | ||
| } | ||
|
|
||
| @property (assign, nonatomic) id<GHTestOutlineViewModelDelegate> delegate; | ||
|
|
||
| @end |
| @@ -0,0 +1,162 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| // | ||
| // 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 <NSObject> | ||
| @optional | ||
| - (void)testRunnerDidStart:(GHTestRunner *)runner; | ||
| - (void)testRunner:(GHTestRunner *)runner didStartTest:(id<GHTest>)test; // Test started | ||
| - (void)testRunner:(GHTestRunner *)runner didUpdateTest:(id<GHTest>)test; // Test changed | ||
| - (void)testRunner:(GHTestRunner *)runner didEndTest:(id<GHTest>)test; // Test finished | ||
| - (void)testRunnerDidCancel:(GHTestRunner *)runner; | ||
| - (void)testRunnerDidEnd:(GHTestRunner *)runner; | ||
|
|
||
| - (void)testRunner:(GHTestRunner *)runner didLog:(NSString *)message; // Runner logged message | ||
| - (void)testRunner:(GHTestRunner *)runner test:(id<GHTest>)test didLog:(NSString *)message; // Test logged 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 <GHTestDelegate> { | ||
|
|
||
| id<GHTest> test_; // The test to run; Could be a GHTestGroup (suite), GHTestGroup (test case), or GHTest (target/selector) | ||
|
|
||
| NSObject<GHTestRunnerDelegate> *delegate_; // weak | ||
|
|
||
| GHTestOptions options_; | ||
|
|
||
| BOOL running_; | ||
| BOOL cancelling_; | ||
|
|
||
| NSTimeInterval startInterval_; | ||
|
|
||
| NSOperationQueue *operationQueue_; //! If running a suite in operation queue | ||
| } | ||
|
|
||
| @property (retain) id<GHTest> test; | ||
| @property (assign) NSObject<GHTestRunnerDelegate> *delegate; | ||
| @property (assign) GHTestOptions options; | ||
| @property (readonly) GHTestStats stats; | ||
| @property (readonly, getter=isRunning) BOOL running; | ||
| @property (readonly, getter=isCancelling) BOOL cancelling; | ||
| @property (readonly) NSTimeInterval interval; | ||
| @property (retain, nonatomic) NSOperationQueue *operationQueue; | ||
|
|
||
|
|
||
| /*! | ||
| Create runner for test. | ||
| @param test | ||
| */ | ||
| - (id)initWithTest:(id<GHTest>)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; | ||
|
|
||
| /*! | ||
| Create runner for class and method. | ||
| @param testClassName | ||
| @param methodName | ||
| @result Runner | ||
| */ | ||
| + (GHTestRunner *)runnerForTestClassName:(NSString *)testClassName methodName:(NSString *)methodName; | ||
|
|
||
| /*! | ||
| 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 0 is success, otherwise the failure count | ||
| */ | ||
| + (int)run; | ||
|
|
||
| - (void)runInBackground; | ||
|
|
||
| /*! | ||
| Start the test runner with the default test. | ||
| @result 0 is success, otherwise the failure count | ||
| */ | ||
| - (int)runTests; | ||
|
|
||
| - (void)cancel; | ||
|
|
||
| - (void)setInParallel:(BOOL)inParallel; | ||
| - (BOOL)isInParallel; | ||
|
|
||
| /*! | ||
| Write message to console. | ||
| */ | ||
| - (void)log:(NSString *)message; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond | ||
|
|
| @@ -0,0 +1,118 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import "GHTestGroup.h" | ||
|
|
||
| /*! | ||
| If set, will run it as a "test filter" like the env variable TEST. | ||
| */ | ||
| extern NSString *GHUnitTest; | ||
|
|
||
|
|
||
| /*! | ||
| 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<GHTest> which represents a target and a selector. | ||
| A test group is a collection of tests; A collection of id<GHTest> (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<GHTestDelegate>)delegate; | ||
|
|
||
| /*! | ||
| Creates a suite of all tests. | ||
| Will load all classes that subclass from GHTestCase, SenTestCase or GTMTestCase (or register test case class). | ||
| @result Suite | ||
| */ | ||
| + (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; | ||
|
|
||
| /*! | ||
| Create suite of tests that start with prefix. | ||
| @param prefix If test case class starts with the prefix; If nil or empty string, returns all tests | ||
| @param options Compare options | ||
| */ | ||
| + (GHTestSuite *)suiteWithPrefix:(NSString *)prefix options:(NSStringCompareOptions)options; | ||
|
|
||
| /*! | ||
| Suite for a single test/method. | ||
| @param testCaseClass | ||
| @param method | ||
| @result Suite | ||
| */ | ||
| + (GHTestSuite *)suiteWithTestCaseClass:(Class)testCaseClass method:(SEL)method; | ||
|
|
||
| /*! | ||
| Return test suite based on environment (TEST=TestFoo/foo) | ||
| @result Suite | ||
| */ | ||
| + (GHTestSuite *)suiteFromEnv; | ||
|
|
||
| @end | ||
|
|
||
| @interface GHTestSuite (JUnitXML) | ||
|
|
||
| - (BOOL)writeJUnitXML:(NSError **)error; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,103 @@ | ||
| // | ||
| // 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" | ||
| #import "GHTestOutlineViewModel.h" | ||
|
|
||
| #import "BWSplitView.h" | ||
|
|
||
| @interface GHTestViewController : NSViewController <GHTestRunnerDelegate, GHTestOutlineViewModelDelegate> { | ||
|
|
||
| IBOutlet BWSplitView *_splitView; | ||
| IBOutlet NSView *_statusView; | ||
| IBOutlet NSView *_detailsView; | ||
| IBOutlet NSOutlineView *_outlineView; | ||
| IBOutlet NSTextView *_textView; | ||
| IBOutlet NSSegmentedControl *_textSegmentedControl; | ||
| IBOutlet NSSegmentedControl *_segmentedControl; | ||
| IBOutlet NSSearchField *_searchField; | ||
|
|
||
| BOOL wrapInTextView_; | ||
| NSString *status_; | ||
| double statusProgress_; | ||
| BOOL runInParallel_; | ||
| NSString *runLabel_; | ||
|
|
||
| NSString *exceptionFilename_; | ||
| NSInteger exceptionLineNumber_; | ||
|
|
||
| GHTestSuite *suite_; | ||
|
|
||
| GHTestOutlineViewModel *dataSource_; | ||
| BOOL running_; | ||
| } | ||
|
|
||
| @property (assign, nonatomic) BOOL wrapInTextView; | ||
| @property (readonly, nonatomic) id<GHTest> selectedTest; | ||
| @property (readonly, nonatomic) GHTestOutlineViewModel *dataSource; | ||
|
|
||
| @property (retain, nonatomic) NSString *status; | ||
| @property (assign, nonatomic) double statusProgress; | ||
| @property (retain, nonatomic) NSString *runLabel; | ||
|
|
||
| @property (retain, nonatomic) GHTestSuite *suite; | ||
| @property (assign, nonatomic, getter=isRunning) BOOL running; | ||
|
|
||
| @property (retain, nonatomic) NSString *exceptionFilename; | ||
| @property (assign, nonatomic) NSInteger exceptionLineNumber; | ||
|
|
||
|
|
||
| - (void)loadTestSuite; | ||
|
|
||
| - (void)selectFirstFailure; | ||
|
|
||
| - (IBAction)copy:(id)sender; | ||
| - (IBAction)runTests:(id)sender; | ||
| - (IBAction)toggleDetails:(id)sender; | ||
| - (IBAction)updateTextSegment:(id)sender; | ||
| - (IBAction)updateMode:(id)sender; | ||
| - (IBAction)updateSearchFilter:(id)sender; | ||
| - (IBAction)openExceptionFilename:(id)sender; | ||
| - (IBAction)rerunTest:(id)sender; | ||
|
|
||
| - (id<GHTest>)selectedTest; | ||
|
|
||
| - (void)runTests; | ||
|
|
||
| - (void)reload; | ||
|
|
||
| - (void)loadDefaults; | ||
| - (void)saveDefaults; | ||
|
|
||
| - (BOOL)isShowingDetails; | ||
|
|
||
| - (void)selectRow:(NSInteger)row; | ||
|
|
||
| @end |
| @@ -0,0 +1,167 @@ | ||
| // | ||
| // GHTest.h | ||
| // GHUnit | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import "GHTestGroup.h" | ||
|
|
||
| @class GHTestNode; | ||
|
|
||
| @protocol GHTestNodeDelegate <NSObject> | ||
| - (void)testNodeDidChange:(GHTestNode *)node; | ||
| @end | ||
|
|
||
| typedef enum { | ||
| GHTestNodeFilterNone = 0, | ||
| GHTestNodeFilterFailed = 1 | ||
| } GHTestNodeFilter; | ||
|
|
||
| /*! | ||
| Test view model for use in a tree view. | ||
| */ | ||
| @interface GHTestViewModel : NSObject <GHTestNodeDelegate> { | ||
|
|
||
| NSString *identifier_; | ||
| GHTestSuite *suite_; | ||
| GHTestNode *root_; | ||
|
|
||
| GHTestRunner *runner_; | ||
|
|
||
| NSMutableDictionary *map_; // id<GHTest>#identifier -> GHTestNode | ||
|
|
||
| BOOL editing_; | ||
|
|
||
| NSMutableDictionary *defaults_; | ||
| } | ||
|
|
||
| @property (readonly, nonatomic) GHTestNode *root; | ||
| @property (assign, nonatomic, getter=isEditing) BOOL editing; | ||
|
|
||
| /*! | ||
| Create view model with root test group node. | ||
| @param identifier Unique identifier for test model (used to load defaults) | ||
| @param suite | ||
| */ | ||
| - (id)initWithIdentifier:(NSString *)identifier suite:(GHTestSuite *)suite; | ||
|
|
||
| - (NSString *)name; | ||
| - (NSString *)statusString:(NSString *)prefix; | ||
|
|
||
| /*! | ||
| Get the test node from the test. | ||
| @param test | ||
| */ | ||
| - (GHTestNode *)findTestNode:(id<GHTest>)test; | ||
|
|
||
| - (GHTestNode *)findFailure; | ||
| - (GHTestNode *)findFailureFromNode:(GHTestNode *)node; | ||
|
|
||
| /*! | ||
| 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<GHTest>)test; | ||
|
|
||
| - (void)loadDefaults; | ||
| - (void)saveDefaults; | ||
|
|
||
| /*! | ||
| Run with current test suite. | ||
| */ | ||
| - (void)run:(id<GHTestRunnerDelegate>)delegate inParallel:(BOOL)inParallel options:(GHTestOptions)options; | ||
|
|
||
| - (void)cancel; | ||
|
|
||
| - (BOOL)isRunning; | ||
|
|
||
| @end | ||
|
|
||
|
|
||
| @interface GHTestNode : NSObject { | ||
|
|
||
| id<GHTest> test_; | ||
| NSMutableArray */*of GHTestNode*/children_; | ||
| NSMutableArray */* of GHTestNode*/filteredChildren_; | ||
|
|
||
| id<GHTestNodeDelegate> delegate_; | ||
| GHTestNodeFilter filter_; | ||
| NSString *textFilter_; | ||
| } | ||
|
|
||
| @property (readonly, nonatomic) NSArray */* of GHTestNode*/children; | ||
| @property (readonly, nonatomic) id<GHTest> test; | ||
| @property (assign, nonatomic) id<GHTestNodeDelegate> delegate; | ||
| @property (assign, nonatomic) GHTestNodeFilter filter; | ||
| @property (retain, nonatomic) NSString *textFilter; | ||
|
|
||
| - (id)initWithTest:(id<GHTest>)test children:(NSArray */*of id<GHTest>*/)children source:(GHTestViewModel *)source; | ||
| + (GHTestNode *)nodeWithTest:(id<GHTest>)test children:(NSArray */*of id<GHTest>*/)children source:(GHTestViewModel *)source; | ||
|
|
||
| - (NSString *)identifier; | ||
| - (NSString *)name; | ||
| - (NSString *)nameWithStatus; | ||
|
|
||
| - (GHTestStatus)status; | ||
| - (NSString *)statusString; | ||
| - (NSString *)stackTrace; | ||
| - (NSString *)exceptionFilename; | ||
| - (NSInteger)exceptionLineNumber; | ||
| - (NSString *)log; | ||
| - (BOOL)isRunning; | ||
| - (BOOL)isDisabled; | ||
| - (BOOL)isHidden; | ||
| - (BOOL)isEnded; | ||
| - (BOOL)isGroupTest; // YES if test has "sub tests" | ||
|
|
||
| - (BOOL)isSelected; | ||
| - (void)setSelected:(BOOL)selected; | ||
|
|
||
| - (BOOL)hasChildren; | ||
| - (BOOL)failed; | ||
|
|
||
| - (void)notifyChanged; | ||
|
|
||
| - (void)setFilter:(GHTestNodeFilter)filter textFilter:(NSString *)textFilter; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,41 @@ | ||
| // | ||
| // 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; | ||
|
|
||
| - (IBAction)runTests:(id)sender; | ||
| - (IBAction)copy:(id)sender; | ||
|
|
||
| @end |
| @@ -0,0 +1,148 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" NSString *GHUStackTraceFromException(NSException *e); | ||
| #else | ||
| extern NSString *GHUStackTraceFromException(NSException *e); | ||
| #endif | ||
|
|
||
| // 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". | ||
| @result Array of initialized (and autoreleased) test case classes in an autoreleased array. | ||
| */ | ||
| - (NSArray *)loadAllTestCases; | ||
|
|
||
| /*! | ||
| Load tests from target. | ||
| @result Array of id<GHTest> | ||
| */ | ||
| - (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; | ||
|
|
||
| /*! | ||
| Format test exception. | ||
| @param exception | ||
| @result Description | ||
| */ | ||
| + (NSString *)descriptionForException:(NSException *)exception; | ||
|
|
||
| /*! | ||
| Filename for cause of test exception. | ||
| @param test | ||
| @result Filename | ||
| */ | ||
| + (NSString *)exceptionFilenameForTest:(id<GHTest>)test; | ||
|
|
||
| /*! | ||
| Line number for cause of test exception. | ||
| @param test | ||
| @result Line number | ||
| */ | ||
| + (NSInteger)exceptionLineNumberForTest:(id<GHTest>)test; | ||
|
|
||
| /*! | ||
| Run test. | ||
| @param target | ||
| @param selector | ||
| @param exception Exception, if set, is retained and should be released by the caller. | ||
| @param interval Time to run the test | ||
| @param reraiseExceptions If YES, will re-raise exceptions | ||
| */ | ||
| + (BOOL)runTestWithTarget:(id)target selector:(SEL)selector exception:(NSException **)exception | ||
| interval:(NSTimeInterval *)interval reraiseExceptions:(BOOL)reraiseExceptions; | ||
|
|
||
| /*! | ||
| Same as normal runTest without catching exceptions. | ||
| */ | ||
| + (BOOL)runTestOrRaiseWithTarget:(id)target selector:(SEL)selector exception:(NSException **)exception interval:(NSTimeInterval *)interval; | ||
|
|
||
| @end | ||
|
|
||
| @protocol GHSenTestCase | ||
| - (void)raiseAfterFailure; | ||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,40 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| @interface NSObject(GHUSwizzle) | ||
|
|
||
| + (void)ghu_swizzleMethod:(SEL)original withMethod:(SEL)alternate; | ||
| + (void)ghu_swizzleClassMethod:(SEL)original withClassMethod:(SEL)alternate; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond | ||
|
|
| @@ -0,0 +1,105 @@ | ||
| // | ||
| // GTMStackTrace.h | ||
| // | ||
| // Copyright 2007-2008 Google Inc. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); you may not | ||
| // use this file except in compliance with the License. You may obtain a copy | ||
| // of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | ||
| // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | ||
| // License for the specific language governing permissions and limitations under | ||
| // the License. | ||
| // | ||
|
|
||
| #include <CoreFoundation/CoreFoundation.h> | ||
| #import "GTMDefines.h" | ||
|
|
||
| #ifdef __cplusplus | ||
| extern "C" { | ||
| #endif | ||
|
|
||
| struct GHU_GTMAddressDescriptor { | ||
| const void *address; // address | ||
| const char *symbol; // nearest symbol to address | ||
| const char *class_name; // if it is an obj-c method, the method's class | ||
| BOOL is_class_method; // if it is an obj-c method, type of method | ||
| const char *filename; // file that the method came from. | ||
| }; | ||
|
|
||
| // Returns a string containing a nicely formatted stack trace. | ||
| // | ||
| // This function gets the stack trace for the current thread. It will | ||
| // be from the caller of GTMStackTrace upwards to the top the calling stack. | ||
| // Typically this function will be used along with some logging, | ||
| // as in the following: | ||
| // | ||
| // MyAppLogger(@"Should never get here:\n%@", GTMStackTrace()); | ||
| // | ||
| // Here is a sample stack trace returned from this function: | ||
| // | ||
| // #0 0x00002d92 D () [/Users/me/./StackLog] | ||
| // #1 0x00002e45 C () [/Users/me/./StackLog] | ||
| // #2 0x00002e53 B () [/Users/me/./StackLog] | ||
| // #3 0x00002e61 A () [/Users/me/./StackLog] | ||
| // #4 0x00002e6f main () [/Users/me/./StackLog] | ||
| // #5 0x00002692 tart () [/Users/me/./StackLog] | ||
| // #6 0x000025b9 tart () [/Users/me/./StackLog] | ||
| // | ||
|
|
||
| NSString *GHU_GTMStackTrace(void); | ||
|
|
||
| #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5 | ||
| // Returns a string containing a nicely formatted stack trace from the | ||
| // exception. Only available on 10.5 or later, uses | ||
| // -[NSException callStackReturnAddresses]. | ||
| // | ||
| NSString *GHU_GTMStackTraceFromException(NSException *e); | ||
| #endif | ||
|
|
||
| #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | ||
| // Returns an array of program counters from the current thread's stack. | ||
| // *** You should probably use GTMStackTrace() instead of this function *** | ||
| // However, if you actually want all the PCs in "void *" form, then this | ||
| // funtion is more convenient. This will include PCs of GTMStaceTrace and | ||
| // its inner utility functions that you may want to strip out. | ||
| // | ||
| // You can use +[NSThread callStackReturnAddresses] in 10.5 or later. | ||
| // | ||
| // Args: | ||
| // outPcs - an array of "void *" pointers to the program counters found on the | ||
| // current thread's stack. | ||
| // count - the number of entries in the outPcs array | ||
| // | ||
| // Returns: | ||
| // The number of program counters actually added to outPcs. | ||
| // | ||
| NSUInteger GHU_GTMGetStackProgramCounters(void *outPcs[], NSUInteger count); | ||
| #endif // MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 | ||
|
|
||
| // Returns an array of GTMAddressDescriptors from the current thread's stack. | ||
| // *** You should probably use GTMStackTrace() instead of this function *** | ||
| // However, if you actually want all the PCs with symbols, this is the way | ||
| // to get them. There is no memory allocations done, so no clean up is required | ||
| // except for the caller to free outDescs if they allocated it themselves. | ||
| // This will include PCs of GTMStaceTrace and its inner utility functions that | ||
| // you may want to strip out. | ||
| // | ||
| // Args: | ||
| // outDescs - an array of "struct GTMAddressDescriptor" pointers corresponding | ||
| // to the program counters found on the current thread's stack. | ||
| // count - the number of entries in the outDescs array | ||
| // | ||
| // Returns: | ||
| // The number of program counters actually added to outPcs. | ||
| // | ||
| NSUInteger GHU_GTMGetStackAddressDescriptors(struct GHU_GTMAddressDescriptor outDescs[], | ||
| NSUInteger count); | ||
|
|
||
| #ifdef __cplusplus | ||
| } | ||
| #endif |
| @@ -0,0 +1,97 @@ | ||
| // | ||
| // NSException+GHTestFailureExceptions.h | ||
| // | ||
| // Created by Johannes Rudolph on 23.09.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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| extern NSString *const GHTestFilenameKey; | ||
| extern NSString *const GHTestLineNumberKey; | ||
| extern NSString *const GHTestFailureException; | ||
|
|
||
|
|
||
| // GTM_BEGIN | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| @interface NSException(GHUTestFailureExceptions) | ||
| + (NSException *)ghu_failureInFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInCondition:(NSString *)condition | ||
| isTrue:(BOOL)isTrue | ||
| inFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInEqualityBetweenObject:(id)left | ||
| andObject:(id)right | ||
| inFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInInequalityBetweenObject:(id)left | ||
| andObject:(id)right | ||
| inFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInEqualityBetweenValue:(NSValue *)left | ||
| andValue:(NSValue *)right | ||
| withAccuracy:(NSValue *)accuracy | ||
| inFile:(NSString *)filename | ||
| atLine:(int) ineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInRaise:(NSString *)expression | ||
| inFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| + (NSException *)ghu_failureInRaise:(NSString *)expression | ||
| exception:(NSException *)exception | ||
| inFile:(NSString *)filename | ||
| atLine:(int)lineNumber | ||
| withDescription:(NSString *)formatString, ...; | ||
| @end | ||
|
|
||
| // GTM_END | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,71 @@ | ||
| // | ||
| // NSValue+GHValueFormatter.h | ||
| // | ||
| // Created by Johannes Rudolph on 23.9.2009. | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| // | ||
| // 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. | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| // SENTE_BEGIN | ||
| @interface NSValue(GHValueFormatter) | ||
| - (NSString *)ghu_contentDescription; | ||
| @end | ||
| // SENTE_END | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,4 @@ | ||
|
|
||
| #include "GHUnit.xcconfig" | ||
|
|
||
| GCC_OPTIMIZATION_LEVEL = 0 |
| @@ -0,0 +1,15 @@ | ||
|
|
||
| #include "Shared.xcconfig" | ||
|
|
||
| ARCHS = $(ARCHS_STANDARD_32_64_BIT) | ||
| INSTALL_PATH = @rpath | ||
| DYLIB_COMPATIBILITY_VERSION = 0 | ||
| DYLIB_CURRENT_VERSION = $(GHUNIT_VERSION) | ||
| LD_RUNPATH_SEARCH_PATHS = @loader_path/../Frameworks | ||
| INFOPLIST_FILE = Info.plist | ||
| PRODUCT_NAME = GHUnit | ||
| WRAPPER_EXTENSION = framework | ||
| GCC_ENABLE_OBJC_GC = supported | ||
| GCC_PRECOMPILE_PREFIX_HEADER = YES | ||
| GCC_PREFIX_HEADER = GHUnit_Prefix.pch | ||
| GCC_MODEL_TUNING = G5 |
| @@ -0,0 +1,22 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| <plist version="1.0"> | ||
| <dict> | ||
| <key>CFBundleDevelopmentRegion</key> | ||
| <string>English</string> | ||
| <key>CFBundleExecutable</key> | ||
| <string>GHUnit</string> | ||
| <key>CFBundleIdentifier</key> | ||
| <string>me.rel.GHUnit</string> | ||
| <key>CFBundleInfoDictionaryVersion</key> | ||
| <string>6.0</string> | ||
| <key>CFBundleName</key> | ||
| <string>GHUnit</string> | ||
| <key>CFBundlePackageType</key> | ||
| <string>FMWK</string> | ||
| <key>CFBundleSignature</key> | ||
| <string>GABE</string> | ||
| <key>CFBundleVersion</key> | ||
| <string>0.4.28</string> | ||
| </dict> | ||
| </plist> |
| @@ -0,0 +1,47 @@ | ||
| // | ||
| // BWSplitView.h | ||
| // BWToolkit | ||
| // | ||
| // Created by Brandon Walkin (www.brandonwalkin.com) and Fraser Kuyvenhoven. | ||
| // All code is provided under the New BSD license. | ||
| // | ||
|
|
||
| #import <Cocoa/Cocoa.h> | ||
|
|
||
| @interface BWSplitView : NSSplitView | ||
| #if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 // on lines like this to not confuse IB | ||
| <NSSplitViewDelegate> | ||
| #endif | ||
| { | ||
| NSColor *color; | ||
| BOOL colorIsEnabled, checkboxIsEnabled, dividerCanCollapse, collapsibleSubviewCollapsed; | ||
| id secondaryDelegate; | ||
| NSMutableDictionary *minValues, *maxValues, *minUnits, *maxUnits; | ||
| NSMutableDictionary *resizableSubviewPreferredProportion, *nonresizableSubviewPreferredSize; | ||
| NSArray *stateForLastPreferredCalculations; | ||
| int collapsiblePopupSelection; | ||
| float uncollapsedSize; | ||
|
|
||
| // Collapse button | ||
| NSButton *toggleCollapseButton; | ||
| BOOL isAnimating; | ||
| } | ||
|
|
||
| @property (retain) NSMutableDictionary *minValues, *maxValues, *minUnits, *maxUnits; | ||
| @property (retain) NSMutableDictionary *resizableSubviewPreferredProportion, *nonresizableSubviewPreferredSize; | ||
| @property (retain) NSArray *stateForLastPreferredCalculations; | ||
| @property (retain) NSButton *toggleCollapseButton; | ||
| @property BOOL collapsibleSubviewCollapsed; | ||
| @property int collapsiblePopupSelection; | ||
| @property BOOL dividerCanCollapse; | ||
|
|
||
| // The split view divider color | ||
| @property (copy) NSColor *color; | ||
|
|
||
| // Flag for whether a custom divider color is enabled. If not, the standard divider color is used. | ||
| @property BOOL colorIsEnabled; | ||
|
|
||
| // Call this method to collapse or expand a subview configured as collapsible in the IB inspector. | ||
| - (IBAction)toggleCollapse:(id)sender; | ||
|
|
||
| @end |
| @@ -0,0 +1,155 @@ | ||
| // | ||
| // 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, //!< Unknown wait status | ||
| kGHUnitWaitStatusSuccess, //!< Wait status success | ||
| kGHUnitWaitStatusFailure, //!< Wait status failure | ||
| kGHUnitWaitStatusCancelled //!< Wait status cancelled | ||
| }; | ||
|
|
||
| /*! | ||
| Asynchronous test case with wait and notify. | ||
| If notify occurs before wait has started (if it was a synchronous call), this test | ||
| case will still work. | ||
| Be sure to call prepare before the asynchronous method (otherwise an exception will raise). | ||
| @code | ||
| @interface MyAsyncTest : GHAsyncTestCase { } | ||
| @end | ||
| @implementation MyAsyncTest | ||
| - (void)testSuccess { | ||
| [self prepare]; | ||
| // Do asynchronous task here | ||
| [self performSelector:@selector(_succeed) withObject:nil afterDelay:0.1]; | ||
| [self waitForStatus: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. | ||
| // To ignore the check, forSelector can be NULL. | ||
| [self notify:kGHUnitWaitStatusSuccess forSelector:@selector(testSuccess)]; | ||
| } | ||
| @end | ||
| @endcode | ||
| */ | ||
| @interface GHAsyncTestCase : GHTestCase { | ||
|
|
||
| NSInteger waitForStatus_; | ||
| NSInteger notifiedStatus_; | ||
|
|
||
| BOOL prepared_; // Whether prepared was called before waitForStatus: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 waitForStatus:kGHUnitWaitStatusSuccess timeout:1.0]; | ||
| } | ||
| @endcode | ||
| @param status kGHUnitWaitStatusSuccess, kGHUnitWaitStatusFailure or custom status | ||
| @param timeout Timeout in seconds | ||
| */ | ||
| - (void)waitForStatus:(NSInteger)status timeout:(NSTimeInterval)timeout; | ||
|
|
||
| /*! | ||
| @deprecated | ||
| */ | ||
| - (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 waiting of status for test selector. | ||
| @param status 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; | ||
|
|
||
| /*! | ||
| Notify waiting of status for any selector. | ||
| @param status Status, for example, kGHUnitWaitStatusSuccess | ||
| */ | ||
| - (void)notify:(NSInteger)status; | ||
|
|
||
| /*! | ||
| Run the run loops for the specified interval. | ||
| @param interval | ||
| @author Adapted from Robert Palmer, pauseForTimeout | ||
| */ | ||
| - (void)runForInterval:(NSTimeInterval)interval; | ||
|
|
||
| @end |
| @@ -0,0 +1,50 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| /*! | ||
| 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 | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,173 @@ | ||
| // | ||
| // 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. | ||
| // | ||
|
|
||
| //! @cond DEV | ||
|
|
||
| #import <Foundation/Foundation.h> | ||
|
|
||
| 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 waitForStatus: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 to connection delegate. | ||
| @param data Data to send | ||
| @param statusCode HTTP status code | ||
| @param MIMEType Mime type | ||
| @param afterDelay Delay | ||
| */ | ||
| - (void)receiveData:(NSData *)data statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType 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 Path to load data 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; | ||
|
|
||
| /*! | ||
| Sends mock response, sends data, and then calls finish. | ||
| (For asynchronous requests) | ||
| @param data Data to load. 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)receiveData:(NSData *)data statusCode:(NSInteger)statusCode MIMEType:(NSString *)MIMEType afterDelay:(NSTimeInterval)delay; | ||
|
|
||
| /*! | ||
| Calls connection:didFailWithError: on delegate after specified delay. | ||
| @param error The error to pass to the delegate. | ||
| @param delay Delay before responding (if < 0, there is no delay) | ||
| */ | ||
| - (void)failWithError:(NSError *)error afterDelay:(NSTimeInterval)delay; | ||
|
|
||
| @end | ||
|
|
||
| //! @endcond |
| @@ -0,0 +1,132 @@ | ||
| // | ||
| // GHNSInvocation+Utils.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 <Foundation/Foundation.h> | ||
|
|
||
| // | ||
| // Creates arguments NSArray from var args, with first object named 'object' | ||
| // - (void)methodName:(id)arg1 withObjects:object, ... | ||
| // | ||
| #define GHConvertVarArgs(object) \ | ||
| NSMutableArray *arguments = [NSMutableArray array]; \ | ||
| do { \ | ||
| id arg; \ | ||
| va_list args; \ | ||
| if (object) { \ | ||
| [arguments addObject:object]; \ | ||
| va_start(args, object); \ | ||
| while ((arg = va_arg(args, id))) \ | ||
| [arguments addObject:arg]; \ | ||
| va_end(args); \ | ||
| } \ | ||
| } while(0); | ||
|
|
||
| @interface NSInvocation (GHUtils_GHUNIT) | ||
|
|
||
| /*! | ||
| Invoke on main thread. | ||
| @param waitUntilDone Whether to join on the call | ||
| */ | ||
| - (void)ghu_invokeOnMainThread:(BOOL)waitUntilDone; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param withObjects (Variable) Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param arguments Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector with multiple arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param afterDelay Time interval for delay (in seconds) | ||
| @param arguments Arguments list | ||
| */ | ||
| + (id)ghu_invokeWithTarget:(id)target selector:(SEL)selector afterDelay:(NSTimeInterval)delay arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param withObjects Nil terminated list of (object) arguments; Use [NSNull null] for nil arguments | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param arguments Arguments list | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Invoke target selector on main thread with multiple arguments. | ||
| @param target Target | ||
| @param selector Action | ||
| @param waitUntilDone Whether to wait for call to finish | ||
| @param afterDelay Time interval for delay (in seconds) | ||
| @param arguments Arguments list | ||
| */ | ||
| + (void)ghu_invokeTargetOnMainThread:(id)target selector:(SEL)selector waitUntilDone:(BOOL)waitUntilDone afterDelay:(NSTimeInterval)delay arguments:(NSArray *)arguments; | ||
|
|
||
| /*! | ||
| Create invocation with variable arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param hasReturnValue Will be set to YES, if there is a return value | ||
| @param withObjects (Variable) Arguments list | ||
| */ | ||
| + (NSInvocation *)ghu_invocationWithTarget:(id)target selector:(SEL)selector hasReturnValue:(BOOL *)hasReturnValue withObjects:object, ...; | ||
|
|
||
| /*! | ||
| Create invocation with variable arguments. | ||
| Use [NSNull null] for nil arguments. | ||
| @param target Invocation target | ||
| @param selector Method | ||
| @param hasReturnValue Will be set to YES, if there is a return value | ||
| @param arguments Arguments array | ||
| */ | ||
| + (NSInvocation *)ghu_invocationWithTarget:target selector:(SEL)selector hasReturnValue:(BOOL *)hasReturnValue arguments:(NSArray *)arguments; | ||
|
|
||
| @end |