├── ILCannedURLProtocol.h ├── ILCannedURLProtocol.m ├── ILCannedURLProtocolTests.h ├── ILCannedURLProtocolTests.m ├── ILProfilerCompat.c ├── ILTestImage.h ├── ILTestImage.m ├── OCHamcrestMatchers ├── ILDispatchQueueAssert.h ├── ILDispatchQueueAssert.m ├── ILDispatchQueueMatcher.h └── ILDispatchQueueMatcher.m └── README.mdown /ILCannedURLProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILCannedURLProtocol.h 3 | // 4 | // Created by Claus Broch on 10/09/11. 5 | // Copyright 2011 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import 29 | 30 | @protocol ILCannedURLProtocolDelegate 31 | - (NSData*)responseDataForClient:(id)client request:(NSURLRequest*)request; 32 | @optional 33 | - (BOOL)shouldInitWithRequest:(NSURLRequest*)request; 34 | - (NSURL *)redirectForClient:(id)client request:(NSURLRequest *)request; 35 | - (NSInteger)statusCodeForClient:(id)client request:(NSURLRequest*)request; 36 | - (NSDictionary*)headersForClient:(id)client request:(NSURLRequest*)request; 37 | @end 38 | 39 | 40 | typedef NSData *(^ResponseDataBlock)(id client, NSURLRequest *request); 41 | typedef BOOL (^ShouldInitRequestBlock)(NSURLRequest *request); 42 | typedef NSURL *(^RedirectBlockForClient)(id client, NSURLRequest *request); 43 | typedef NSInteger (^StatusCodeBlock)(id client, NSURLRequest* request); 44 | typedef NSDictionary *(^HeadersBlock)(id client, NSURLRequest* request); 45 | 46 | @interface ILCannedURLProtocol : NSURLProtocol 47 | 48 | + (void)setDelegate:(id)delegate; 49 | 50 | + (void)setStartLoadingBlock:(void(^)(NSURLRequest *request))block; 51 | + (void)setResponseDataBlock:(ResponseDataBlock)responseDataBlock; 52 | + (void)setShouldInitWithRequestBlock:(ShouldInitRequestBlock)shouldInitRequestBlock; 53 | + (void)setRedirectForClientBlock:(RedirectBlockForClient)redirectForClientBlock; 54 | + (void)setStatusCodeBlock:(StatusCodeBlock)statusCodeBlock; 55 | + (void)setHeadersBlock:(HeadersBlock)headersBlock; 56 | 57 | + (void)setCannedResponseData:(NSData*)data; 58 | + (void)setCannedHeaders:(NSDictionary*)headers; 59 | + (void)setCannedStatusCode:(NSInteger)statusCode; 60 | + (void)setCannedError:(NSError*)error; 61 | 62 | + (void)setSupportedMethods:(NSArray*)methods; 63 | + (void)setSupportedSchemes:(NSArray*)schemes; 64 | + (void)setSupportedBaseURL:(NSURL*)baseURL; 65 | 66 | + (void)setResponseDelay:(CGFloat)responseDelay; 67 | 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /ILCannedURLProtocol.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILCannedURLProtocol.m 3 | // 4 | // Created by Claus Broch on 10/09/11. 5 | // Copyright 2011 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import "ILCannedURLProtocol.h" 29 | 30 | static id gILDelegate = nil; 31 | 32 | static void(^startLoadingBlock)(NSURLRequest *request) = nil; 33 | static NSData *gILCannedResponseData = nil; 34 | static NSDictionary *gILCannedHeaders = nil; 35 | static NSInteger gILCannedStatusCode = 200; 36 | static NSError *gILCannedError = nil; 37 | static NSArray *gILSupportedMethods = nil; 38 | static NSArray *gILSupportedSchemes = nil; 39 | static NSURL *gILSupportedBaseURL = nil; 40 | static CGFloat gILResponseDelay = 0; 41 | 42 | static ResponseDataBlock gResposeDataBlock = nil; 43 | static ShouldInitRequestBlock gShouldInitRequestBlock = nil; 44 | static RedirectBlockForClient gRedirectBlockForClient = nil; 45 | static StatusCodeBlock gStatusCodeBlock = nil; 46 | static HeadersBlock gHeadersBlock = nil; 47 | 48 | @implementation ILCannedURLProtocol 49 | 50 | + (void)setStartLoadingBlock:(void(^)(NSURLRequest *request))block { 51 | Block_release(startLoadingBlock); 52 | startLoadingBlock = Block_copy(block); 53 | } 54 | 55 | + (BOOL)canInitWithRequest:(NSURLRequest *)request { 56 | 57 | BOOL canInit = YES; 58 | 59 | if (gILDelegate && [gILDelegate respondsToSelector:@selector(shouldInitWithRequest:)]) { 60 | canInit = [gILDelegate shouldInitWithRequest:request]; 61 | } else { 62 | canInit = ( 63 | (!gILSupportedBaseURL || [request.URL.absoluteString hasPrefix:gILSupportedBaseURL.absoluteString]) && 64 | (!gILSupportedMethods || [gILSupportedMethods containsObject:request.HTTPMethod]) && 65 | (!gILSupportedSchemes || [gILSupportedSchemes containsObject:request.URL.scheme]) 66 | ); 67 | } 68 | 69 | if (gShouldInitRequestBlock) { 70 | canInit = gShouldInitRequestBlock(request); 71 | } 72 | 73 | return canInit; 74 | } 75 | 76 | + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request { 77 | return request; 78 | } 79 | 80 | + (void)setDelegate:(id)delegate { 81 | gILDelegate = delegate; 82 | } 83 | 84 | + (void)setCannedResponseData:(NSData*)data { 85 | if(data != gILCannedResponseData) { 86 | [gILCannedResponseData release]; 87 | gILCannedResponseData = [data retain]; 88 | } 89 | } 90 | 91 | + (void)setCannedHeaders:(NSDictionary*)headers { 92 | if(headers != gILCannedHeaders) { 93 | [gILCannedHeaders release]; 94 | gILCannedHeaders = [headers retain]; 95 | } 96 | } 97 | 98 | + (void)setCannedStatusCode:(NSInteger)statusCode { 99 | gILCannedStatusCode = statusCode; 100 | } 101 | 102 | + (void)setCannedError:(NSError*)error { 103 | if(error != gILCannedError) { 104 | [gILCannedError release]; 105 | gILCannedError = [error retain]; 106 | } 107 | } 108 | 109 | - (NSCachedURLResponse *)cachedResponse { 110 | return nil; 111 | } 112 | 113 | + (void)setSupportedMethods:(NSArray*)methods { 114 | if(methods != gILSupportedMethods) { 115 | [gILSupportedMethods release]; 116 | gILSupportedMethods = [methods retain]; 117 | } 118 | } 119 | 120 | + (void)setSupportedSchemes:(NSArray*)schemes { 121 | if(schemes != gILSupportedSchemes) { 122 | [gILSupportedSchemes release]; 123 | gILSupportedSchemes = [schemes retain]; 124 | } 125 | } 126 | 127 | + (void)setSupportedBaseURL:(NSURL*)baseURL { 128 | if(baseURL != gILSupportedBaseURL) { 129 | [gILSupportedBaseURL release]; 130 | gILSupportedBaseURL = [baseURL retain]; 131 | } 132 | } 133 | 134 | 135 | + (void)setResponseDelay:(CGFloat)responseDelay { 136 | gILResponseDelay = responseDelay; 137 | } 138 | 139 | + (void)setResponseDataBlock:(ResponseDataBlock)responseDataBlock { 140 | Block_release(gResposeDataBlock); 141 | gResposeDataBlock = Block_copy(responseDataBlock); 142 | } 143 | 144 | + (void)setShouldInitWithRequestBlock:(ShouldInitRequestBlock)shouldInitRequestBlock { 145 | Block_release(gShouldInitRequestBlock); 146 | gShouldInitRequestBlock = Block_copy(shouldInitRequestBlock); 147 | } 148 | 149 | + (void)setRedirectForClientBlock:(RedirectBlockForClient)redirectForClientBlock { 150 | Block_release(gRedirectBlockForClient); 151 | gRedirectBlockForClient = Block_copy(redirectForClientBlock); 152 | } 153 | 154 | + (void)setStatusCodeBlock:(StatusCodeBlock)statusCodeBlock { 155 | Block_release(gStatusCodeBlock); 156 | gStatusCodeBlock = Block_copy(statusCodeBlock); 157 | } 158 | 159 | + (void)setHeadersBlock:(HeadersBlock)headersBlock { 160 | Block_release(gHeadersBlock); 161 | gHeadersBlock = Block_copy(headersBlock); 162 | } 163 | 164 | - (void)startLoading { 165 | NSURLRequest *request = [self request]; 166 | id client = [self client]; 167 | 168 | if (startLoadingBlock) { 169 | startLoadingBlock(request); 170 | } 171 | 172 | NSInteger statusCode = gILCannedStatusCode; 173 | NSDictionary *headers = gILCannedHeaders; 174 | NSData *responseData = gILCannedResponseData; 175 | 176 | // Handle redirects 177 | NSURL *redirectUrl = nil; 178 | 179 | if (gRedirectBlockForClient) { 180 | redirectUrl = gRedirectBlockForClient(client,request); 181 | } else if (gILDelegate && [gILDelegate respondsToSelector:@selector(redirectForClient:request:)]) { 182 | redirectUrl = [gILDelegate redirectForClient:client request:request]; 183 | } 184 | 185 | if (redirectUrl) { 186 | NSHTTPURLResponse *redirectResponse = [[NSHTTPURLResponse alloc] initWithURL:[request URL] 187 | statusCode:302 188 | HTTPVersion:@"HTTP/1.1" 189 | headerFields: [NSDictionary dictionaryWithObject:[redirectUrl absoluteString] forKey:@"Location"]]; 190 | 191 | [client URLProtocol:self wasRedirectedToRequest:[NSURLRequest requestWithURL:redirectUrl] redirectResponse:redirectResponse]; 192 | return; 193 | } 194 | 195 | if (gILCannedError) { 196 | [NSThread sleepForTimeInterval:gILResponseDelay]; 197 | [client URLProtocol:self didFailWithError:gILCannedError]; 198 | 199 | } else { 200 | 201 | 202 | 203 | if (gILDelegate && [gILDelegate respondsToSelector:@selector(responseDataForClient:request:)]) { 204 | 205 | if ([gILDelegate respondsToSelector:@selector(statusCodeForClient:request:)]) { 206 | statusCode = [gILDelegate statusCodeForClient:client request:request]; 207 | } 208 | 209 | if ([gILDelegate respondsToSelector:@selector(headersForClient:request:)]) { 210 | headers = [gILDelegate headersForClient:client request:request]; 211 | } 212 | 213 | responseData = [gILDelegate responseDataForClient:client request:request]; 214 | } 215 | 216 | if (gResposeDataBlock) { 217 | responseData = gResposeDataBlock(client,request); 218 | } 219 | 220 | if (gStatusCodeBlock) { 221 | statusCode = gStatusCodeBlock(client,request); 222 | } 223 | 224 | if (gHeadersBlock) { 225 | headers = gHeadersBlock(client,request); 226 | } 227 | 228 | NSHTTPURLResponse *response = [[NSHTTPURLResponse alloc] initWithURL:[request URL] 229 | statusCode:statusCode 230 | HTTPVersion:@"HTTP/1.1" 231 | headerFields:headers]; 232 | 233 | [NSThread sleepForTimeInterval:gILResponseDelay]; 234 | //NSDate *loopUntil = [NSDate dateWithTimeIntervalSinceNow:gILResponseDelay]; 235 | //[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode beforeDate:loopUntil]; 236 | 237 | 238 | [client URLProtocol:self didReceiveResponse:response cacheStoragePolicy:NSURLCacheStorageNotAllowed]; 239 | [client URLProtocol:self didLoadData:responseData]; 240 | [client URLProtocolDidFinishLoading:self]; 241 | 242 | [response release]; 243 | } 244 | } 245 | 246 | - (void)stopLoading { 247 | } 248 | 249 | @end 250 | -------------------------------------------------------------------------------- /ILCannedURLProtocolTests.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILCannedURLProtocolTests.h 3 | // TactilizeKit 4 | // 5 | // Created by Arnaud Coomans on 03/07/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "ILCannedURLProtocol.h" 11 | 12 | @interface ILCannedURLProtocolTests : SenTestCase 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /ILCannedURLProtocolTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILCannedURLProtocolTests.m 3 | // TactilizeKit 4 | // 5 | // Created by Arnaud Coomans on 03/07/12. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | 10 | //TODO urls should use example.com (ietf domain for example purposes) 11 | 12 | #import "ILCannedURLProtocolTests.h" 13 | 14 | @implementation ILCannedURLProtocolTests 15 | 16 | - (void)setUp { 17 | [super setUp]; 18 | 19 | [NSURLProtocol registerClass:[ILCannedURLProtocol class]]; 20 | 21 | [ILCannedURLProtocol setDelegate:nil]; 22 | 23 | [ILCannedURLProtocol setCannedStatusCode:200]; 24 | [ILCannedURLProtocol setCannedHeaders:nil]; 25 | [ILCannedURLProtocol setCannedResponseData:nil]; 26 | [ILCannedURLProtocol setCannedError:nil]; 27 | 28 | [ILCannedURLProtocol setSupportedMethods:nil]; 29 | [ILCannedURLProtocol setSupportedSchemes:nil]; 30 | [ILCannedURLProtocol setSupportedBaseURL:nil]; 31 | 32 | [ILCannedURLProtocol setResponseDataBlock:nil]; 33 | [ILCannedURLProtocol setShouldInitWithRequestBlock:nil]; 34 | [ILCannedURLProtocol setRedirectForClientBlock:nil]; 35 | [ILCannedURLProtocol setStatusCodeBlock:nil]; 36 | [ILCannedURLProtocol setHeadersBlock:nil]; 37 | 38 | [ILCannedURLProtocol setResponseDelay:0]; 39 | } 40 | 41 | - (void)testCanInitWithGETHTTPRequestWithSupportedSchemesAndMethodsNotSet { 42 | 43 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 44 | request.HTTPMethod = @"GET"; 45 | 46 | [ILCannedURLProtocol setSupportedMethods:nil]; 47 | [ILCannedURLProtocol setSupportedSchemes:nil]; 48 | 49 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 50 | } 51 | 52 | - (void)testCanInitWithGETHTTPRequestWithSupportedSchemesAndMethodsEmpty { 53 | 54 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 55 | request.HTTPMethod = @"GET"; 56 | 57 | [ILCannedURLProtocol setSupportedMethods:[NSArray array]]; 58 | [ILCannedURLProtocol setSupportedSchemes:[NSArray array]]; 59 | 60 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 61 | } 62 | 63 | - (void)testCanInitWithGETHTTPRequestWithSupportedHTTPSchemesAndGETMethods{ 64 | 65 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 66 | request.HTTPMethod = @"GET"; 67 | 68 | [ILCannedURLProtocol setSupportedMethods:[NSArray arrayWithObject:@"GET"]]; 69 | [ILCannedURLProtocol setSupportedSchemes:[NSArray arrayWithObject:@"http"]]; 70 | 71 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 72 | } 73 | 74 | - (void)testCanInitWithPOSTHTTPSRequestWithSupportedHTTPSSchemesAndPOSTMethods{ 75 | 76 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://example.com"]]; 77 | request.HTTPMethod = @"POST"; 78 | 79 | [ILCannedURLProtocol setSupportedMethods:[NSArray arrayWithObject:@"POST"]]; 80 | [ILCannedURLProtocol setSupportedSchemes:[NSArray arrayWithObject:@"https"]]; 81 | 82 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 83 | } 84 | 85 | - (void)testCanInitWithPOSTHTTPRequestWithSupportedHTTPSchemesAndGETMethods{ 86 | 87 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 88 | request.HTTPMethod = @"POST"; 89 | 90 | [ILCannedURLProtocol setSupportedMethods:[NSArray arrayWithObject:@"GET"]]; 91 | [ILCannedURLProtocol setSupportedSchemes:[NSArray arrayWithObject:@"http"]]; 92 | 93 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 94 | } 95 | 96 | - (void)testCanInitWithGETHTTPRequestWithSupportedHTTPSSchemesAndGETMethods{ 97 | 98 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 99 | request.HTTPMethod = @"GET"; 100 | 101 | [ILCannedURLProtocol setSupportedMethods:[NSArray arrayWithObject:@"GET"]]; 102 | [ILCannedURLProtocol setSupportedSchemes:[NSArray arrayWithObject:@"https"]]; 103 | 104 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol does not support a GET HTTP request"); 105 | } 106 | 107 | - (void)testCanInitWithRequestWithSupportedBaseURL { 108 | 109 | NSMutableURLRequest *goodRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testCanInitWithRequestWithSupportedBaseURL"]]; 110 | NSMutableURLRequest *badRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.org"]]; 111 | 112 | [ILCannedURLProtocol setSupportedBaseURL:[NSURL URLWithString:@"http://example.com"]]; 113 | 114 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:goodRequest], @"ILCannedURLProtocol does not support a request with base url"); 115 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:badRequest], @"ILCannedURLProtocol does not support a request with base url"); 116 | } 117 | 118 | 119 | - (void)testStartLoadingWithoutDelegate { 120 | 121 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com"]]; 122 | 123 | id requestObject = [NSDictionary dictionaryWithObjectsAndKeys: 124 | [NSArray arrayWithObjects:[NSNumber numberWithInt:0], [NSNumber numberWithInt:1], [NSNumber numberWithInt:2], nil], @"array", 125 | @"hello", @"string", 126 | nil]; 127 | 128 | NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 129 | [ILCannedURLProtocol setCannedResponseData:requestData]; 130 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 131 | 132 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 133 | 134 | STAssertNotNil(responseObject, @"no canned response from http request"); 135 | STAssertTrue([responseObject isKindOfClass:[NSDictionary class]], @"canned response has wrong format (not dictionary)"); 136 | } 137 | 138 | - (void)testStartLoadingWithDelegate { 139 | 140 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testStartLoadingWithDelegate"]]; 141 | 142 | [ILCannedURLProtocol setDelegate:self]; 143 | 144 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 145 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 146 | 147 | STAssertNotNil(responseObject, @"no canned response from http request"); 148 | STAssertTrue([responseObject isKindOfClass:[NSDictionary class]], @"canned response has wrong format (not dictionary)"); 149 | STAssertTrue([[responseObject objectForKey:@"testName"] isEqual:@"testStartLoadingWithDelegate"], @"wrong canned response"); 150 | } 151 | 152 | - (void)testAgainStartLoadingWithDelegate { 153 | 154 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testAgainStartLoadingWithDelegate"]]; 155 | 156 | [ILCannedURLProtocol setDelegate:self]; 157 | 158 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 159 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 160 | 161 | STAssertNotNil(responseObject, @"no canned response from http request"); 162 | STAssertTrue([responseObject isKindOfClass:[NSDictionary class]], @"canned response has wrong format (not dictionary)"); 163 | STAssertTrue([[responseObject objectForKey:@"testName"] isEqual:@"testAgainStartLoadingWithDelegate"], @"wrong canned response"); 164 | } 165 | 166 | - (void)testStartLoadingWithDelegatePlainJSONResponse { 167 | 168 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testStartLoadingWithDelegatePlainJSONResponse"]]; 169 | 170 | [ILCannedURLProtocol setDelegate:self]; 171 | 172 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 173 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 174 | 175 | STAssertNotNil(responseObject, @"no canned response from http request"); 176 | STAssertTrue([responseObject isKindOfClass:[NSDictionary class]], @"canned response has wrong format (not dictionary)"); 177 | STAssertTrue([[responseObject objectForKey:@"testName"] isEqual:@"testStartLoadingWithDelegatePlainJSONResponse"], @"wrong canned response"); 178 | } 179 | 180 | - (void)testCanInitWithRequestWithDelegateShouldInitWithRequest { 181 | 182 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testCanInitWithRequestWithDelegateShouldInitWithRequest"]]; 183 | 184 | [ILCannedURLProtocol setDelegate:self]; 185 | 186 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol delegate returned shouldInitWithRequest NO"); 187 | } 188 | 189 | - (void)testCanInitWithRequestWithDelegateShouldInitWithRequestNO { 190 | 191 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testCanInitWithRequestWithDelegateShouldInitWithRequestNO"]]; 192 | 193 | [ILCannedURLProtocol setDelegate:self]; 194 | 195 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol delegate returned shouldInitWithRequest YES"); 196 | } 197 | 198 | 199 | - (void)testRedirectForClient { 200 | 201 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect-test.com"]]; 202 | 203 | [ILCannedURLProtocol setDelegate:self]; 204 | 205 | NSURLResponse *response = nil; 206 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 207 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 208 | 209 | STAssertNotNil(response, @"no canned response from http request"); 210 | STAssertNotNil(responseObject, @"no canned response object from http request"); 211 | STAssertEqualObjects(response.URL.absoluteString, @"http://redirected-response.com", @"response should have been redirected"); 212 | STAssertTrue([[responseObject objectForKey:@"REDIRECTED"] isEqual:@"YES"], @"wrong canned response"); 213 | } 214 | 215 | - (void)testResponseBlock { 216 | 217 | [ILCannedURLProtocol setResponseDataBlock:^NSData *(id client, NSURLRequest *request) { 218 | 219 | NSData *requestData = nil; 220 | 221 | if ([request.URL.absoluteString isEqual:@"http://example.com/testResponseBlock"]) { 222 | id requestObject = [NSDictionary dictionaryWithObjectsAndKeys:@"testResponseBlock", @"testName", nil]; 223 | requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 224 | 225 | } 226 | 227 | return requestData; 228 | }]; 229 | 230 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testResponseBlock"]]; 231 | 232 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; 233 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 234 | 235 | STAssertNotNil(responseObject, @"no canned response from http request"); 236 | STAssertTrue([responseObject isKindOfClass:[NSDictionary class]], @"canned response has wrong format (not dictionary)"); 237 | STAssertTrue([[responseObject objectForKey:@"testName"] isEqual:@"testResponseBlock"], @"wrong canned response"); 238 | } 239 | 240 | - (void)testCanInitWithRequestWithShouldInitWithRequestBlock { 241 | 242 | [ILCannedURLProtocol setShouldInitWithRequestBlock:^BOOL(NSURLRequest *request) { 243 | if ([request.URL.absoluteString isEqual:@"http://example.com/testCanInitWithRequestWithShouldInitWithRequestBlock"]) { 244 | return YES; 245 | } 246 | return NO; 247 | }]; 248 | 249 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testCanInitWithRequestWithShouldInitWithRequestBlock"]]; 250 | 251 | STAssertTrue([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol delegate returned shouldInitWithRequest NO"); 252 | } 253 | 254 | - (void)testCanInitWithRequestWithShouldInitWithRequestBlockNO { 255 | 256 | [ILCannedURLProtocol setShouldInitWithRequestBlock:^BOOL(NSURLRequest *request) { 257 | if ([request.URL.absoluteString isEqual:@"http://example.com/testCanInitWithRequestWithShouldInitWithRequestBlockNO"]) { 258 | return NO; 259 | } 260 | return YES; 261 | }]; 262 | 263 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testCanInitWithRequestWithShouldInitWithRequestBlockNO"]]; 264 | 265 | STAssertFalse([ILCannedURLProtocol canInitWithRequest:request], @"ILCannedURLProtocol delegate returned shouldInitWithRequest YES"); 266 | } 267 | 268 | 269 | - (void)testRedirectForClientBlock { 270 | 271 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://redirect-test.com/testRedirectForClientBlock"]]; 272 | 273 | 274 | [ILCannedURLProtocol setRedirectForClientBlock:^NSURL *(id client, NSURLRequest *request) { 275 | if ([request.HTTPMethod isEqualToString:@"GET"] && [request.URL.absoluteString isEqualToString:@"http://redirect-test.com/testRedirectForClientBlock"]) { 276 | return [NSURL URLWithString:@"http://redirected-response.com/testRedirectForClientBlock"]; 277 | } 278 | 279 | return nil; 280 | }]; 281 | 282 | [ILCannedURLProtocol setResponseDataBlock:^NSData *(id client, NSURLRequest *request) { 283 | NSData *requestData = nil; 284 | 285 | if ([request.URL.absoluteString isEqual:@"http://redirected-response.com/testRedirectForClientBlock"]) { 286 | id requestObject = [NSDictionary dictionaryWithObject:@"YES" forKey:@"REDIRECTED"]; 287 | requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 288 | } 289 | return requestData; 290 | }]; 291 | 292 | NSURLResponse *response = nil; 293 | NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 294 | id responseObject = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; 295 | 296 | STAssertNotNil(response, @"no canned response from http request"); 297 | STAssertNotNil(responseObject, @"no canned response object from http request"); 298 | STAssertEqualObjects(response.URL.absoluteString, @"http://redirected-response.com/testRedirectForClientBlock", @"response should have been redirected"); 299 | STAssertTrue([[responseObject objectForKey:@"REDIRECTED"] isEqual:@"YES"], @"wrong canned response"); 300 | } 301 | 302 | - (void)testStatusCodeBlock { 303 | 304 | [ILCannedURLProtocol setStatusCodeBlock:^NSInteger(id client, NSURLRequest *request) { 305 | if ([request.URL.absoluteString isEqual:@"http://example.com/testStatusCodeBlock"]) { 306 | return 204; 307 | } 308 | return 201; 309 | }]; 310 | 311 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testStatusCodeBlock"]]; 312 | 313 | NSHTTPURLResponse *response = nil; 314 | [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 315 | 316 | STAssertEquals([response statusCode], 204L, @"Wrong status code"); 317 | } 318 | 319 | - (void)testHeadersBlock { 320 | 321 | [ILCannedURLProtocol setHeadersBlock:^NSDictionary *(id client, NSURLRequest *request) { 322 | if ([request.URL.absoluteString isEqual:@"http://example.com/testHeadersBlock"]) { 323 | return @{@"key": @"value"}; 324 | } 325 | return nil; 326 | }]; 327 | 328 | NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://example.com/testHeadersBlock"]]; 329 | 330 | NSHTTPURLResponse *response = nil; 331 | [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil]; 332 | 333 | NSDictionary *headers = [response allHeaderFields]; 334 | STAssertNotNil(headers, @"no headers"); 335 | STAssertTrue([[headers objectForKey:@"key"] isEqual:@"value"], @"no key on the header"); 336 | } 337 | 338 | 339 | #pragma mark - ILCannedURLProtocolDelegate 340 | 341 | - (NSURL *)redirectForClient:(id)client request:(NSURLRequest *)request 342 | { 343 | if ([request.HTTPMethod isEqualToString:@"GET"] && [request.URL.absoluteString isEqualToString:@"http://redirect-test.com"]) { 344 | return [NSURL URLWithString:@"http://redirected-response.com"]; 345 | } 346 | 347 | return nil; 348 | } 349 | 350 | - (NSData*)responseDataForClient:(id)client request:(NSURLRequest*)request { 351 | 352 | NSData *requestData = nil; 353 | 354 | if ([request.URL.absoluteString isEqual:@"http://example.com/testStartLoadingWithDelegate"]) { 355 | id requestObject = [NSDictionary dictionaryWithObjectsAndKeys:@"testStartLoadingWithDelegate", @"testName", nil]; 356 | requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 357 | 358 | } 359 | 360 | if ([request.URL.absoluteString isEqual:@"http://example.com/testAgainStartLoadingWithDelegate"]) { 361 | id requestObject = [NSDictionary dictionaryWithObjectsAndKeys:@"testAgainStartLoadingWithDelegate", @"testName", nil]; 362 | requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 363 | 364 | } 365 | 366 | if ([request.URL.absoluteString isEqual:@"http://example.com/testStartLoadingWithDelegatePlainJSONResponse"]) { 367 | requestData = [@"{\"testName\":\"testStartLoadingWithDelegatePlainJSONResponse\"}" dataUsingEncoding:NSUnicodeStringEncoding]; 368 | } 369 | 370 | if ([request.URL.absoluteString isEqual:@"http://redirected-response.com"]) { 371 | id requestObject = [NSDictionary dictionaryWithObject:@"YES" forKey:@"REDIRECTED"]; 372 | requestData = [NSJSONSerialization dataWithJSONObject:requestObject options:0 error:nil]; 373 | } 374 | 375 | 376 | return requestData; 377 | } 378 | 379 | 380 | - (BOOL)shouldInitWithRequest:(NSURLRequest*)request { 381 | if ([request.URL.absoluteString isEqual:@"http://example.com/testCanInitWithRequestWithDelegateShouldInitWithRequest"]) { 382 | return YES; 383 | } 384 | 385 | if ([request.URL.absoluteString isEqual:@"http://example.com/testCanInitWithRequestWithDelegateShouldInitWithRequestNO"]) { 386 | return NO; 387 | } 388 | 389 | return YES; 390 | } 391 | 392 | 393 | @end 394 | -------------------------------------------------------------------------------- /ILProfilerCompat.c: -------------------------------------------------------------------------------- 1 | // 2 | // ILProfilerCompat.c 3 | // 4 | // Created by Claus Broch on 03/02/12. 5 | // Copyright (c) 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #include 29 | 30 | // 31 | // This file provides a workaround for an error that sometimes occurs when enabling code coverage 32 | // metrics on iOS using LLVM/Clang and libprofile_rt.dylib: 33 | // 34 | // Detected an attempt to call a symbol in system libraries that is not present on the iPhone: 35 | // fopen$UNIX2003 called from function llvm_gcda_start_file in image ... 36 | // 37 | // To fix this problem simply include this file in your testing target build. 38 | // 39 | 40 | FILE *fopen$UNIX2003(const char *filename, const char *mode); 41 | size_t fwrite$UNIX2003(const void *ptr, size_t size, size_t nitems, FILE *stream); 42 | 43 | FILE *fopen$UNIX2003(const char *filename, const char *mode) { 44 | return fopen(filename, mode); 45 | } 46 | 47 | size_t fwrite$UNIX2003(const void *ptr, size_t size, size_t nitems, FILE *stream) { 48 | return fwrite(ptr, size, nitems, stream); 49 | } -------------------------------------------------------------------------------- /ILTestImage.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILTestImage.h 3 | // 4 | // Created by Claus Broch on 21/04/12. 5 | // Copyright 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import 29 | 30 | typedef void (^ValidateDrawInRect)(NSRect drawRect, NSRect fromRect, NSCompositingOperation operation, CGFloat fraction); 31 | 32 | @interface ILTestImage : NSObject { 33 | NSSize _size; 34 | ValidateDrawInRect _validateDrawInRect; 35 | } 36 | 37 | // NSImage properties 38 | @property (assign, nonatomic) NSSize size; 39 | 40 | // Test properties - perform validation in the block passed 41 | @property (assign, nonatomic) ValidateDrawInRect validateDrawInRect; 42 | 43 | - (id)initWithSize:(NSSize)size; 44 | - (void)setSize:(NSSize)aSize; 45 | - (NSSize)size; 46 | - (void)drawInRect:(NSRect)rect fromRect:(NSRect)fromRect operation:(NSCompositingOperation)op fraction:(CGFloat)delta; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /ILTestImage.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILTestImage.m 3 | // 4 | // Created by Claus Broch on 21/04/12. 5 | // Copyright 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import "ILTestImage.h" 29 | 30 | @implementation ILTestImage 31 | @synthesize size=_size; 32 | @synthesize validateDrawInRect=_validateDrawInRect; 33 | 34 | - (id)initWithSize:(NSSize)size { 35 | self = [super init]; 36 | if(self) { 37 | _size = size; 38 | } 39 | return self; 40 | } 41 | 42 | - (void)setSize:(NSSize)aSize { 43 | _size = aSize; 44 | } 45 | 46 | - (NSSize)size { 47 | return _size; 48 | } 49 | 50 | - (void)drawInRect:(NSRect)rect fromRect:(NSRect)fromRect operation:(NSCompositingOperation)op fraction:(CGFloat)delta { 51 | if(_validateDrawInRect) { 52 | _validateDrawInRect(rect, fromRect, op, delta); 53 | } 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /OCHamcrestMatchers/ILDispatchQueueAssert.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILDispatchQueueAssert.h 3 | // 4 | // Created by Claus Broch on 5/9/2012. 5 | // Copyright (c) 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import 29 | 30 | @protocol HCMatcher; 31 | 32 | 33 | OBJC_EXPORT void HC_assertThatDispatchQueueWithLocation(id testCase, dispatch_queue_t actual, id matcher, const char* fileName, int lineNumber); 34 | 35 | #define HC_assertThatDispatchQueue(actual, matcher) \ 36 | HC_assertThatDispatchQueueWithLocation(self, actual, matcher, __FILE__, __LINE__) 37 | 38 | #ifdef HC_SHORTHAND 39 | #define assertThatDispatchQueue HC_assertThatDispatchQueue 40 | #endif 41 | 42 | -------------------------------------------------------------------------------- /OCHamcrestMatchers/ILDispatchQueueAssert.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILDispatchQueueAssert.m 3 | // 4 | // Created by Claus Broch on 5/9/2012. 5 | // Copyright (c) 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import 29 | 30 | #import "ILDispatchQueueAssert.h" 31 | 32 | OBJC_EXPORT void HC_assertThatDispatchQueueWithLocation(id testCase, dispatch_queue_t actual, id matcher, const char* fileName, int lineNumber) { 33 | HC_assertThatWithLocation(testCase, [NSValue value:&actual withObjCType:@encode(dispatch_queue_t)], matcher, fileName, lineNumber); 34 | } 35 | -------------------------------------------------------------------------------- /OCHamcrestMatchers/ILDispatchQueueMatcher.h: -------------------------------------------------------------------------------- 1 | // 2 | // ILDispatchQueueMatcher.h 3 | // 4 | // Created by Claus Broch on 4/9/2012. 5 | // Copyright (c) 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import 29 | 30 | OBJC_EXPORT id HC_equalToDispatchQueue(dispatch_queue_t targetQueue); 31 | 32 | #ifdef HC_SHORTHAND 33 | #define equalToDispatchQueue HC_equalToDispatchQueue 34 | #endif 35 | -------------------------------------------------------------------------------- /OCHamcrestMatchers/ILDispatchQueueMatcher.m: -------------------------------------------------------------------------------- 1 | // 2 | // ILDispatchQueueMatcher.m 3 | // 4 | // Created by Claus Broch on 4/9/2012. 5 | // Copyright (c) 2012 Infinite Loop. All rights reserved. 6 | // 7 | // Redistribution and use in source and binary forms, with or without modification, are permitted 8 | // provided that the following conditions are met: 9 | // 10 | // - Redistributions of source code must retain the above copyright notice, this list of conditions 11 | // and the following disclaimer. 12 | // - Redistributions in binary form must reproduce the above copyright notice, this list of 13 | // conditions and the following disclaimer in the documentation and/or other materials provided 14 | // with the distribution. 15 | // - Neither the name of Infinite Loop nor the names of its contributors may be used to endorse or 16 | // promote products derived from this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR 19 | // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 21 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 | // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY 25 | // WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 | // 27 | 28 | #import "ILDispatchQueueMatcher.h" 29 | #import 30 | 31 | OBJC_EXPORT id HC_equalToDispatchQueue(dispatch_queue_t targetQueue) { 32 | return [HCIsEqual isEqualTo:[NSValue value:&targetQueue withObjCType:@encode(dispatch_queue_t)]]; 33 | } 34 | -------------------------------------------------------------------------------- /README.mdown: -------------------------------------------------------------------------------- 1 | 2 | # ILTesting 3 | 4 | 5 | ILTesting provides a collection of Objective C helper classes primarily for assisting with testing. That is, if you can call the current content of one class a collection. 6 | 7 | ### ILCannedURLProtocol 8 | 9 | ILCannedURLProtocol is intended for unit and mock testing of code that makes http requests. It will intercept the standard http protocol and respond with a predefined set of test data every time the test is executed. This way any outside influences can be eliminated from the test results. 10 | 11 | In order to use ILCannedURLProtocol, insert the following code in your test case before executing the code under test: 12 | 13 | [NSURLProtocol registerClass:[ILCannedURLProtocol class]]; 14 | [ILCannedURLProtocol setCannedStatusCode:200]; 15 | [ILCannedURLProtocol setCannedHeaders:testHeaders]; 16 | [ILCannedURLProtocol setCannedResponseData:testData]; 17 | 18 | Make sure to unregister the ILCannedURLProtocol after each use: 19 | 20 | [NSURLProtocol unregisterClass:[ILCannedURLProtocol class]]; 21 | 22 | See also: 23 | 24 | * [Infinite Blog](http://www.infinite-loop.dk/blog/2011/09/using-nsurlprotocol-for-injecting-test-data/) - Using NSURLProtocol for Injecting Test Data 25 | 26 | 27 | ### ILProfilerCompat.c 28 | 29 | This file provides a workaround for an error that sometimes occurs when enabling code coverage 30 | metrics on iOS using LLVM/Clang and libprofile_rt.dylib: 31 | 32 | > Detected an attempt to call a symbol in system libraries that is not present on the iPhone: 33 | > fopen$UNIX2003 called from function llvm_gcda_start_file in image ... 34 | 35 | To fix this problem simply include this file in your testing target build. 36 | 37 | 38 | --- 39 | 40 | Feel free to add enhancements, bug fixes, etc. and provide them back to the community! 41 | 42 | 43 | Thanks, 44 | 45 | Claus Broch 46 | --------------------------------------------------------------------------------