├── .gitignore ├── LICENSE ├── OHHTTPStubs ├── Info.plist ├── OHHTTPStubs-Info.plist ├── OHHTTPStubs.h ├── OHHTTPStubs.m ├── OHHTTPStubs.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ └── WorkspaceSettings.xcsettings │ └── xcshareddata │ │ └── xcschemes │ │ ├── OHHTTPStubs-Mac.xcscheme │ │ ├── OHHTTPStubs-iOS.xcscheme │ │ └── OHHTTPStubs.xcscheme ├── OHHTTPStubsResponse.h ├── OHHTTPStubsResponse.m └── UnitTests │ ├── AsyncSenTestCase.h │ ├── AsyncSenTestCase.m │ ├── Test Suites │ ├── NSURLConnectionDelegateTests.m │ ├── NSURLConnectionTests.m │ └── WithContentsOfURLTests.m │ ├── UnitTests-Info.plist │ └── UnitTests-Prefix.pch ├── OHHTTPStubsDemo.xcworkspace ├── contents.xcworkspacedata └── xcshareddata │ └── WorkspaceSettings.xcsettings ├── OHHTTPStubsDemo ├── Default-568h@2x.png ├── MainViewController.h ├── MainViewController.m ├── MainViewController.xib ├── OHHTTPStubsDemo-Info.plist ├── OHHTTPStubsDemo-Prefix.pch ├── OHHTTPStubsDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── OHHTTPStubsDemo.xcscheme ├── main.m ├── stub.jpg └── stub.txt └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | xcuserdata 12 | profile 13 | *.moved-aside 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | *********************************************************************************** 24 | * 25 | * Any comment or suggestion welcome. Referencing this project in your AboutBox is appreciated. 26 | * Please tell me if you use this class so we can cross-reference our projects. 27 | * 28 | ***********************************************************************************/ 29 | -------------------------------------------------------------------------------- /OHHTTPStubs/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | 11 | CFBundleIdentifier 12 | com.alisoftware.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | FMWK 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | NSHumanReadableCopyright 26 | Copyright © 2013 AliSoftware. All rights reserved. 27 | NSPrincipalClass 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import 30 | #import "OHHTTPStubsResponse.h" 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | #pragma mark - Types 34 | 35 | typedef OHHTTPStubsResponse*(^OHHTTPStubsRequestHandler)(NSURLRequest* request, BOOL onlyCheck); 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | #pragma mark - Interface 39 | 40 | @interface OHHTTPStubs : NSObject 41 | 42 | //////////////////////////////////////////////////////////////////////////////// 43 | #pragma mark - Singleton methods 44 | 45 | + (OHHTTPStubs*)sharedInstance; 46 | 47 | //////////////////////////////////////////////////////////////////////////////// 48 | #pragma mark - Class Methods 49 | 50 | //! Commmodity method: calls instance method on sharedInstance directly 51 | 52 | // same as addRequestHandler but process the checking and the building of the actual stub in separate blocks for performance 53 | +(id)shouldStubRequestsPassingTest:(BOOL(^)(NSURLRequest* request))shouldReturnStubForRequest 54 | withStubResponse:(OHHTTPStubsResponse*(^)(NSURLRequest* request))handler; 55 | 56 | +(id)addRequestHandler:(OHHTTPStubsRequestHandler)handler; 57 | +(BOOL)removeRequestHandler:(id)handler; 58 | +(void)removeLastRequestHandler; 59 | +(void)removeAllRequestHandlers; 60 | +(void)setEnabled:(BOOL)enabled; 61 | 62 | //////////////////////////////////////////////////////////////////////////////// 63 | #pragma mark - Instance Methods 64 | 65 | -(id)addRequestHandler:(OHHTTPStubsRequestHandler)handler; 66 | -(BOOL)removeRequestHandler:(id)handler; 67 | -(void)removeLastRequestHandler; 68 | -(void)removeAllRequestHandlers; 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import "OHHTTPStubs.h" 30 | 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | #pragma mark - Types 34 | 35 | @interface OHHTTPStubsProtocol : NSURLProtocol @end 36 | 37 | //////////////////////////////////////////////////////////////////////////////// 38 | #pragma mark - Implementation 39 | 40 | @implementation OHHTTPStubs { 41 | NSMutableArray *_requestHandlers; 42 | } 43 | 44 | //////////////////////////////////////////////////////////////////////////////// 45 | #pragma mark - Singleton methods 46 | 47 | + (OHHTTPStubs*)sharedInstance 48 | { 49 | static OHHTTPStubs *sharedInstance = nil; 50 | 51 | static dispatch_once_t predicate; 52 | dispatch_once(&predicate, ^{ 53 | sharedInstance = [[self alloc] init]; 54 | }); 55 | 56 | return sharedInstance; 57 | } 58 | 59 | //////////////////////////////////////////////////////////////////////////////// 60 | #pragma mark - Setup & Teardown 61 | 62 | - (id)init 63 | { 64 | self = [super init]; 65 | if (self) 66 | { 67 | _requestHandlers = [NSMutableArray array]; 68 | [[self class] setEnabled:YES]; 69 | } 70 | return self; 71 | } 72 | 73 | - (void)dealloc 74 | { 75 | [[self class] setEnabled:NO]; 76 | } 77 | 78 | //////////////////////////////////////////////////////////////////////////////// 79 | #pragma mark - Public class methods 80 | 81 | // Commodity methods 82 | +(id)shouldStubRequestsPassingTest:(BOOL(^)(NSURLRequest* request))shouldReturnStubForRequest 83 | withStubResponse:(OHHTTPStubsResponse*(^)(NSURLRequest* request))requestHandler 84 | { 85 | return [self addRequestHandler:^OHHTTPStubsResponse *(NSURLRequest *request, BOOL onlyCheck) 86 | { 87 | BOOL shouldStub = shouldReturnStubForRequest ? shouldReturnStubForRequest(request) : YES; 88 | if (onlyCheck) 89 | { 90 | return shouldStub ? OHHTTPStubsResponseUseStub : OHHTTPStubsResponseDontUseStub; 91 | } 92 | else 93 | { 94 | return (requestHandler && shouldStub) ? requestHandler(request) : nil; 95 | } 96 | }]; 97 | } 98 | 99 | +(id)addRequestHandler:(OHHTTPStubsRequestHandler)handler 100 | { 101 | return [[self sharedInstance] addRequestHandler:handler]; 102 | } 103 | +(BOOL)removeRequestHandler:(id)handler 104 | { 105 | return [[self sharedInstance] removeRequestHandler:handler]; 106 | } 107 | +(void)removeLastRequestHandler 108 | { 109 | [[self sharedInstance] removeLastRequestHandler]; 110 | } 111 | +(void)removeAllRequestHandlers 112 | { 113 | [[self sharedInstance] removeAllRequestHandlers]; 114 | } 115 | 116 | +(void)setEnabled:(BOOL)enabled 117 | { 118 | static BOOL currentEnabledState = NO; 119 | if (enabled && !currentEnabledState) 120 | { 121 | [NSURLProtocol registerClass:[OHHTTPStubsProtocol class]]; 122 | } 123 | else if (!enabled && currentEnabledState) 124 | { 125 | // Force instanciate sharedInstance to avoid it being created later and this turning setEnabled to YES again 126 | (void)[self sharedInstance]; // This way if we call [setEnabled:NO] before any call to sharedInstance it will be kept disabled 127 | [NSURLProtocol unregisterClass:[OHHTTPStubsProtocol class]]; 128 | } 129 | currentEnabledState = enabled; 130 | } 131 | 132 | //////////////////////////////////////////////////////////////////////////////// 133 | #pragma mark - Public instance methods 134 | 135 | -(id)addRequestHandler:(OHHTTPStubsRequestHandler)handler 136 | { 137 | OHHTTPStubsRequestHandler handlerCopy = [handler copy]; 138 | @synchronized(self) { 139 | [_requestHandlers addObject:handlerCopy]; 140 | } 141 | return handlerCopy; 142 | } 143 | 144 | -(BOOL)removeRequestHandler:(id)handler 145 | { 146 | BOOL handlerFound = NO; 147 | 148 | @synchronized(self) { 149 | handlerFound = [_requestHandlers containsObject:handler]; 150 | [_requestHandlers removeObject:handler]; 151 | } 152 | return handlerFound; 153 | } 154 | -(void)removeLastRequestHandler 155 | { 156 | @synchronized(self) { 157 | [_requestHandlers removeLastObject]; 158 | } 159 | } 160 | 161 | -(void)removeAllRequestHandlers 162 | { 163 | @synchronized(self) { 164 | [_requestHandlers removeAllObjects]; 165 | } 166 | } 167 | 168 | - (void)enumerateRequestHandlersWithBlock:(void(^)(OHHTTPStubsRequestHandler handler, BOOL *stop))enumerationBlock { 169 | NSCParameterAssert(enumerationBlock != nil); 170 | 171 | @synchronized(self) { 172 | [_requestHandlers enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 173 | enumerationBlock(obj, stop); 174 | }]; 175 | } 176 | } 177 | 178 | @end 179 | 180 | 181 | //////////////////////////////////////////////////////////////////////////////// 182 | #pragma mark - Private Protocol Class 183 | 184 | @implementation OHHTTPStubsProtocol 185 | 186 | + (BOOL)canInitWithRequest:(NSURLRequest *)request { 187 | __block BOOL canInitWithRequest = NO; 188 | [OHHTTPStubs.sharedInstance enumerateRequestHandlersWithBlock:^ (OHHTTPStubsRequestHandler handler, BOOL *stop) { 189 | id response = handler(request, YES); 190 | canInitWithRequest = response != nil; 191 | if (canInitWithRequest) *stop = YES; 192 | }]; 193 | return canInitWithRequest; 194 | } 195 | 196 | - (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)response client:(id)client 197 | { 198 | return [super initWithRequest:request cachedResponse:nil client:client]; 199 | } 200 | 201 | + (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request 202 | { 203 | return request; 204 | } 205 | 206 | - (NSCachedURLResponse *)cachedResponse 207 | { 208 | return nil; 209 | } 210 | 211 | - (void)startLoading { 212 | NSURLRequest* request = [self request]; 213 | id client = [self client]; 214 | 215 | __block OHHTTPStubsResponse *responseStub = nil; 216 | 217 | [OHHTTPStubs.sharedInstance enumerateRequestHandlersWithBlock:^(OHHTTPStubsRequestHandler handler, BOOL *stop) { 218 | responseStub = handler(request, NO); 219 | if (responseStub != nil) *stop = YES; 220 | }]; 221 | 222 | if (responseStub.error == nil) { 223 | // Send the fake data 224 | 225 | NSTimeInterval canonicalResponseTime = responseStub.responseTime; 226 | if (canonicalResponseTime < 0) { 227 | // Interpret it as a bandwidth in KB/s ( -2 => 2KB/s ) 228 | double bandwidth = -canonicalResponseTime * 1000.0; // in bytes per second 229 | canonicalResponseTime = responseStub.responseData.length / bandwidth; 230 | } 231 | NSTimeInterval requestTime = fabs(canonicalResponseTime * 0.1); 232 | NSTimeInterval responseTime = fabs(canonicalResponseTime - requestTime); 233 | 234 | NSHTTPURLResponse* urlResponse = [[NSHTTPURLResponse alloc] initWithURL:request.URL statusCode:responseStub.statusCode HTTPVersion:@"HTTP/1.1" headerFields:responseStub.httpHeaders]; 235 | 236 | // Cookies handling 237 | if (request.HTTPShouldHandleCookies) { 238 | NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseStub.httpHeaders forURL:request.URL]; 239 | [[NSHTTPCookieStorage sharedHTTPCookieStorage] setCookies:cookies forURL:request.URL mainDocumentURL:request.mainDocumentURL]; 240 | } 241 | 242 | NSString *redirectLocation = responseStub.httpHeaders[@"Location"]; 243 | NSURL *redirectURL = (redirectLocation != nil ? [NSURL URLWithString:redirectLocation] : nil); 244 | NSInteger statusCode = responseStub.statusCode; 245 | 246 | void (^requestBlock)(void); 247 | if (statusCode >= 300 && statusCode < 400 && redirectURL) { 248 | NSURLRequest* redirectRequest = [NSURLRequest requestWithURL:redirectURL]; 249 | 250 | requestBlock = ^{ 251 | [client URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:urlResponse]; 252 | }; 253 | } else { 254 | requestBlock = ^{ 255 | [client URLProtocol:self didReceiveResponse:urlResponse cacheStoragePolicy:NSURLCacheStorageNotAllowed]; 256 | 257 | execute_after(responseTime,^{ 258 | [client URLProtocol:self didLoadData:responseStub.responseData]; 259 | [client URLProtocolDidFinishLoading:self]; 260 | }); 261 | }; 262 | } 263 | 264 | execute_after(requestTime, requestBlock); 265 | } else { 266 | // Send the canned error 267 | execute_after(responseStub.responseTime, ^{ 268 | [client URLProtocol:self didFailWithError:responseStub.error]; 269 | }); 270 | } 271 | } 272 | 273 | - (void)stopLoading 274 | { 275 | 276 | } 277 | 278 | ///////////////////////////////////////////// 279 | // Delayed execution utility methods 280 | ///////////////////////////////////////////// 281 | 282 | //! execute the block after a given amount of seconds 283 | void execute_after(NSTimeInterval delayInSeconds, dispatch_block_t block) 284 | { 285 | if (delayInSeconds > 0) { 286 | dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 287 | dispatch_after(popTime, dispatch_get_current_queue(), block); 288 | } else { 289 | block(); 290 | } 291 | } 292 | 293 | @end 294 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0979357D161B6251006DB5D5 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0979357C161B6251006DB5D5 /* Foundation.framework */; }; 11 | 0979359B161B62C0006DB5D5 /* OHHTTPStubs.m in Sources */ = {isa = PBXBuildFile; fileRef = 09793598161B62C0006DB5D5 /* OHHTTPStubs.m */; }; 12 | 0979359C161B62C0006DB5D5 /* OHHTTPStubsResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 0979359A161B62C0006DB5D5 /* OHHTTPStubsResponse.m */; }; 13 | 09804E4E16A8D60A00ADC660 /* OHHTTPStubs.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 09793597161B62C0006DB5D5 /* OHHTTPStubs.h */; }; 14 | 09804E4F16A8D60A00ADC660 /* OHHTTPStubsResponse.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 09793599161B62C0006DB5D5 /* OHHTTPStubsResponse.h */; }; 15 | 098368D3168FC7920082B1A4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0979357C161B6251006DB5D5 /* Foundation.framework */; }; 16 | 098368DC168FC7920082B1A4 /* AsyncSenTestCase.m in Sources */ = {isa = PBXBuildFile; fileRef = 098368DB168FC7920082B1A4 /* AsyncSenTestCase.m */; }; 17 | 098368E4168FD0E50082B1A4 /* NSURLConnectionTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 098368E3168FD0E50082B1A4 /* NSURLConnectionTests.m */; }; 18 | 098368E8168FE49A0082B1A4 /* libOHHTTPStubs-iOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 09793579161B6251006DB5D5 /* libOHHTTPStubs-iOS.a */; }; 19 | 098368EA168FF9740082B1A4 /* NSURLConnectionDelegateTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 098368E9168FF9740082B1A4 /* NSURLConnectionDelegateTests.m */; }; 20 | 098368EC169000340082B1A4 /* WithContentsOfURLTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 098368EB169000340082B1A4 /* WithContentsOfURLTests.m */; }; 21 | 099C735716903B9800239880 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 099C735616903B9800239880 /* UIKit.framework */; }; 22 | BE17699F1975FACD00EE78ED /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE17699E1975FACD00EE78ED /* XCTest.framework */; }; 23 | F6C37BA216F6C8680082B630 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F6C37BA116F6C8680082B630 /* Cocoa.framework */; }; 24 | F6C37BB416F6C8950082B630 /* OHHTTPStubs.m in Sources */ = {isa = PBXBuildFile; fileRef = 09793598161B62C0006DB5D5 /* OHHTTPStubs.m */; }; 25 | F6C37BB516F6C8980082B630 /* OHHTTPStubsResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = 0979359A161B62C0006DB5D5 /* OHHTTPStubsResponse.m */; }; 26 | F6C37BB616F6C89C0082B630 /* OHHTTPStubsResponse.h in Headers */ = {isa = PBXBuildFile; fileRef = 09793599161B62C0006DB5D5 /* OHHTTPStubsResponse.h */; settings = {ATTRIBUTES = (Public, ); }; }; 27 | F6C37BB716F6C8A20082B630 /* OHHTTPStubs.h in Headers */ = {isa = PBXBuildFile; fileRef = 09793597161B62C0006DB5D5 /* OHHTTPStubs.h */; settings = {ATTRIBUTES = (Public, ); }; }; 28 | /* End PBXBuildFile section */ 29 | 30 | /* Begin PBXCopyFilesBuildPhase section */ 31 | 09804E4D16A8D5F100ADC660 /* CopyFiles */ = { 32 | isa = PBXCopyFilesBuildPhase; 33 | buildActionMask = 2147483647; 34 | dstPath = "include/${PRODUCT_NAME}"; 35 | dstSubfolderSpec = 16; 36 | files = ( 37 | 09804E4E16A8D60A00ADC660 /* OHHTTPStubs.h in CopyFiles */, 38 | 09804E4F16A8D60A00ADC660 /* OHHTTPStubsResponse.h in CopyFiles */, 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 09793579161B6251006DB5D5 /* libOHHTTPStubs-iOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libOHHTTPStubs-iOS.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 0979357C161B6251006DB5D5 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 47 | 09793597161B62C0006DB5D5 /* OHHTTPStubs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OHHTTPStubs.h; sourceTree = ""; }; 48 | 09793598161B62C0006DB5D5 /* OHHTTPStubs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OHHTTPStubs.m; sourceTree = ""; }; 49 | 09793599161B62C0006DB5D5 /* OHHTTPStubsResponse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OHHTTPStubsResponse.h; sourceTree = ""; }; 50 | 0979359A161B62C0006DB5D5 /* OHHTTPStubsResponse.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OHHTTPStubsResponse.m; sourceTree = ""; }; 51 | 09804E5116A8D98900ADC660 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; }; 52 | 09804E5216A8D98900ADC660 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = text; name = README.md; path = ../README.md; sourceTree = ""; }; 53 | 098368CE168FC7920082B1A4 /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 54 | 098368D6168FC7920082B1A4 /* UnitTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "UnitTests-Info.plist"; sourceTree = ""; }; 55 | 098368DA168FC7920082B1A4 /* AsyncSenTestCase.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncSenTestCase.h; sourceTree = ""; }; 56 | 098368DB168FC7920082B1A4 /* AsyncSenTestCase.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AsyncSenTestCase.m; sourceTree = ""; }; 57 | 098368DD168FC7920082B1A4 /* UnitTests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UnitTests-Prefix.pch"; sourceTree = ""; }; 58 | 098368E3168FD0E50082B1A4 /* NSURLConnectionTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLConnectionTests.m; sourceTree = ""; }; 59 | 098368E9168FF9740082B1A4 /* NSURLConnectionDelegateTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSURLConnectionDelegateTests.m; sourceTree = ""; }; 60 | 098368EB169000340082B1A4 /* WithContentsOfURLTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WithContentsOfURLTests.m; sourceTree = ""; }; 61 | 099C735616903B9800239880 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 62 | BE17699E1975FACD00EE78ED /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 63 | F6C37BA016F6C8680082B630 /* OHHTTPStubs.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = OHHTTPStubs.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | F6C37BA116F6C8680082B630 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = Library/Frameworks/Cocoa.framework; sourceTree = DEVELOPER_DIR; }; 65 | F6C37BA416F6C8680082B630 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; }; 66 | F6C37BA516F6C8680082B630 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 67 | F6C37BA616F6C8680082B630 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 68 | F6C37BA916F6C8680082B630 /* OHHTTPStubs-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OHHTTPStubs-Info.plist"; sourceTree = ""; }; 69 | /* End PBXFileReference section */ 70 | 71 | /* Begin PBXFrameworksBuildPhase section */ 72 | 09793576161B6251006DB5D5 /* Frameworks */ = { 73 | isa = PBXFrameworksBuildPhase; 74 | buildActionMask = 2147483647; 75 | files = ( 76 | 0979357D161B6251006DB5D5 /* Foundation.framework in Frameworks */, 77 | ); 78 | runOnlyForDeploymentPostprocessing = 0; 79 | }; 80 | 098368CA168FC7920082B1A4 /* Frameworks */ = { 81 | isa = PBXFrameworksBuildPhase; 82 | buildActionMask = 2147483647; 83 | files = ( 84 | BE17699F1975FACD00EE78ED /* XCTest.framework in Frameworks */, 85 | 099C735716903B9800239880 /* UIKit.framework in Frameworks */, 86 | 098368E8168FE49A0082B1A4 /* libOHHTTPStubs-iOS.a in Frameworks */, 87 | 098368D3168FC7920082B1A4 /* Foundation.framework in Frameworks */, 88 | ); 89 | runOnlyForDeploymentPostprocessing = 0; 90 | }; 91 | F6C37B9C16F6C8680082B630 /* Frameworks */ = { 92 | isa = PBXFrameworksBuildPhase; 93 | buildActionMask = 2147483647; 94 | files = ( 95 | F6C37BA216F6C8680082B630 /* Cocoa.framework in Frameworks */, 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | 0979356E161B6251006DB5D5 = { 103 | isa = PBXGroup; 104 | children = ( 105 | 09804E5216A8D98900ADC660 /* README.md */, 106 | 09804E5116A8D98900ADC660 /* LICENSE */, 107 | 0979357E161B6251006DB5D5 /* OHHTTPStubs */, 108 | 098368D4168FC7920082B1A4 /* UnitTests */, 109 | 0979357B161B6251006DB5D5 /* Frameworks */, 110 | 0979357A161B6251006DB5D5 /* Products */, 111 | ); 112 | sourceTree = ""; 113 | }; 114 | 0979357A161B6251006DB5D5 /* Products */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 09793579161B6251006DB5D5 /* libOHHTTPStubs-iOS.a */, 118 | 098368CE168FC7920082B1A4 /* UnitTests.xctest */, 119 | F6C37BA016F6C8680082B630 /* OHHTTPStubs.framework */, 120 | ); 121 | name = Products; 122 | sourceTree = ""; 123 | }; 124 | 0979357B161B6251006DB5D5 /* Frameworks */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | BE17699E1975FACD00EE78ED /* XCTest.framework */, 128 | 0979357C161B6251006DB5D5 /* Foundation.framework */, 129 | F6C37BA116F6C8680082B630 /* Cocoa.framework */, 130 | F6C37BA316F6C8680082B630 /* Other Frameworks */, 131 | ); 132 | name = Frameworks; 133 | sourceTree = ""; 134 | }; 135 | 0979357E161B6251006DB5D5 /* OHHTTPStubs */ = { 136 | isa = PBXGroup; 137 | children = ( 138 | F6C37BA916F6C8680082B630 /* OHHTTPStubs-Info.plist */, 139 | 09793597161B62C0006DB5D5 /* OHHTTPStubs.h */, 140 | 09793598161B62C0006DB5D5 /* OHHTTPStubs.m */, 141 | 09793599161B62C0006DB5D5 /* OHHTTPStubsResponse.h */, 142 | 0979359A161B62C0006DB5D5 /* OHHTTPStubsResponse.m */, 143 | ); 144 | name = OHHTTPStubs; 145 | sourceTree = SOURCE_ROOT; 146 | }; 147 | 098368D4168FC7920082B1A4 /* UnitTests */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | 098368E5168FD0FF0082B1A4 /* Test Suites */, 151 | 098368DA168FC7920082B1A4 /* AsyncSenTestCase.h */, 152 | 098368DB168FC7920082B1A4 /* AsyncSenTestCase.m */, 153 | 098368D5168FC7920082B1A4 /* Supporting Files */, 154 | ); 155 | path = UnitTests; 156 | sourceTree = ""; 157 | }; 158 | 098368D5168FC7920082B1A4 /* Supporting Files */ = { 159 | isa = PBXGroup; 160 | children = ( 161 | 098368D6168FC7920082B1A4 /* UnitTests-Info.plist */, 162 | 098368DD168FC7920082B1A4 /* UnitTests-Prefix.pch */, 163 | 099C735616903B9800239880 /* UIKit.framework */, 164 | ); 165 | name = "Supporting Files"; 166 | sourceTree = ""; 167 | }; 168 | 098368E5168FD0FF0082B1A4 /* Test Suites */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 098368E3168FD0E50082B1A4 /* NSURLConnectionTests.m */, 172 | 098368E9168FF9740082B1A4 /* NSURLConnectionDelegateTests.m */, 173 | 098368EB169000340082B1A4 /* WithContentsOfURLTests.m */, 174 | ); 175 | path = "Test Suites"; 176 | sourceTree = ""; 177 | }; 178 | F6C37BA316F6C8680082B630 /* Other Frameworks */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | F6C37BA416F6C8680082B630 /* AppKit.framework */, 182 | F6C37BA516F6C8680082B630 /* CoreData.framework */, 183 | F6C37BA616F6C8680082B630 /* Foundation.framework */, 184 | ); 185 | name = "Other Frameworks"; 186 | sourceTree = ""; 187 | }; 188 | /* End PBXGroup section */ 189 | 190 | /* Begin PBXHeadersBuildPhase section */ 191 | F6C37B9D16F6C8680082B630 /* Headers */ = { 192 | isa = PBXHeadersBuildPhase; 193 | buildActionMask = 2147483647; 194 | files = ( 195 | F6C37BB616F6C89C0082B630 /* OHHTTPStubsResponse.h in Headers */, 196 | F6C37BB716F6C8A20082B630 /* OHHTTPStubs.h in Headers */, 197 | ); 198 | runOnlyForDeploymentPostprocessing = 0; 199 | }; 200 | /* End PBXHeadersBuildPhase section */ 201 | 202 | /* Begin PBXNativeTarget section */ 203 | 09793578161B6251006DB5D5 /* OHHTTPStubs-iOS */ = { 204 | isa = PBXNativeTarget; 205 | buildConfigurationList = 09793587161B6251006DB5D5 /* Build configuration list for PBXNativeTarget "OHHTTPStubs-iOS" */; 206 | buildPhases = ( 207 | 09793575161B6251006DB5D5 /* Sources */, 208 | 09793576161B6251006DB5D5 /* Frameworks */, 209 | 09804E4D16A8D5F100ADC660 /* CopyFiles */, 210 | ); 211 | buildRules = ( 212 | ); 213 | dependencies = ( 214 | ); 215 | name = "OHHTTPStubs-iOS"; 216 | productName = OHHTTPStubs; 217 | productReference = 09793579161B6251006DB5D5 /* libOHHTTPStubs-iOS.a */; 218 | productType = "com.apple.product-type.library.static"; 219 | }; 220 | 098368CD168FC7920082B1A4 /* UnitTests */ = { 221 | isa = PBXNativeTarget; 222 | buildConfigurationList = 098368E0168FC7920082B1A4 /* Build configuration list for PBXNativeTarget "UnitTests" */; 223 | buildPhases = ( 224 | 098368C9168FC7920082B1A4 /* Sources */, 225 | 098368CA168FC7920082B1A4 /* Frameworks */, 226 | 098368CB168FC7920082B1A4 /* Resources */, 227 | ); 228 | buildRules = ( 229 | ); 230 | dependencies = ( 231 | ); 232 | name = UnitTests; 233 | productName = "OHHTTPStubs Unit Tests"; 234 | productReference = 098368CE168FC7920082B1A4 /* UnitTests.xctest */; 235 | productType = "com.apple.product-type.bundle.unit-test"; 236 | }; 237 | F6C37B9F16F6C8680082B630 /* OHHTTPStubs */ = { 238 | isa = PBXNativeTarget; 239 | buildConfigurationList = F6C37BB316F6C8680082B630 /* Build configuration list for PBXNativeTarget "OHHTTPStubs" */; 240 | buildPhases = ( 241 | F6C37B9B16F6C8680082B630 /* Sources */, 242 | F6C37B9C16F6C8680082B630 /* Frameworks */, 243 | F6C37B9D16F6C8680082B630 /* Headers */, 244 | F6C37B9E16F6C8680082B630 /* Resources */, 245 | ); 246 | buildRules = ( 247 | ); 248 | dependencies = ( 249 | ); 250 | name = OHHTTPStubs; 251 | productName = OHHTTPStubs; 252 | productReference = F6C37BA016F6C8680082B630 /* OHHTTPStubs.framework */; 253 | productType = "com.apple.product-type.framework"; 254 | }; 255 | /* End PBXNativeTarget section */ 256 | 257 | /* Begin PBXProject section */ 258 | 09793570161B6251006DB5D5 /* Project object */ = { 259 | isa = PBXProject; 260 | attributes = { 261 | LastUpgradeCheck = 0510; 262 | ORGANIZATIONNAME = AliSoftware; 263 | }; 264 | buildConfigurationList = 09793573161B6251006DB5D5 /* Build configuration list for PBXProject "OHHTTPStubs" */; 265 | compatibilityVersion = "Xcode 3.2"; 266 | developmentRegion = English; 267 | hasScannedForEncodings = 0; 268 | knownRegions = ( 269 | en, 270 | ); 271 | mainGroup = 0979356E161B6251006DB5D5; 272 | productRefGroup = 0979357A161B6251006DB5D5 /* Products */; 273 | projectDirPath = ""; 274 | projectRoot = ""; 275 | targets = ( 276 | 09793578161B6251006DB5D5 /* OHHTTPStubs-iOS */, 277 | 098368CD168FC7920082B1A4 /* UnitTests */, 278 | F6C37B9F16F6C8680082B630 /* OHHTTPStubs */, 279 | ); 280 | }; 281 | /* End PBXProject section */ 282 | 283 | /* Begin PBXResourcesBuildPhase section */ 284 | 098368CB168FC7920082B1A4 /* Resources */ = { 285 | isa = PBXResourcesBuildPhase; 286 | buildActionMask = 2147483647; 287 | files = ( 288 | ); 289 | runOnlyForDeploymentPostprocessing = 0; 290 | }; 291 | F6C37B9E16F6C8680082B630 /* Resources */ = { 292 | isa = PBXResourcesBuildPhase; 293 | buildActionMask = 2147483647; 294 | files = ( 295 | ); 296 | runOnlyForDeploymentPostprocessing = 0; 297 | }; 298 | /* End PBXResourcesBuildPhase section */ 299 | 300 | /* Begin PBXSourcesBuildPhase section */ 301 | 09793575161B6251006DB5D5 /* Sources */ = { 302 | isa = PBXSourcesBuildPhase; 303 | buildActionMask = 2147483647; 304 | files = ( 305 | 0979359B161B62C0006DB5D5 /* OHHTTPStubs.m in Sources */, 306 | 0979359C161B62C0006DB5D5 /* OHHTTPStubsResponse.m in Sources */, 307 | ); 308 | runOnlyForDeploymentPostprocessing = 0; 309 | }; 310 | 098368C9168FC7920082B1A4 /* Sources */ = { 311 | isa = PBXSourcesBuildPhase; 312 | buildActionMask = 2147483647; 313 | files = ( 314 | 098368DC168FC7920082B1A4 /* AsyncSenTestCase.m in Sources */, 315 | 098368E4168FD0E50082B1A4 /* NSURLConnectionTests.m in Sources */, 316 | 098368EA168FF9740082B1A4 /* NSURLConnectionDelegateTests.m in Sources */, 317 | 098368EC169000340082B1A4 /* WithContentsOfURLTests.m in Sources */, 318 | ); 319 | runOnlyForDeploymentPostprocessing = 0; 320 | }; 321 | F6C37B9B16F6C8680082B630 /* Sources */ = { 322 | isa = PBXSourcesBuildPhase; 323 | buildActionMask = 2147483647; 324 | files = ( 325 | F6C37BB416F6C8950082B630 /* OHHTTPStubs.m in Sources */, 326 | F6C37BB516F6C8980082B630 /* OHHTTPStubsResponse.m in Sources */, 327 | ); 328 | runOnlyForDeploymentPostprocessing = 0; 329 | }; 330 | /* End PBXSourcesBuildPhase section */ 331 | 332 | /* Begin XCBuildConfiguration section */ 333 | 09793585161B6251006DB5D5 /* Debug */ = { 334 | isa = XCBuildConfiguration; 335 | buildSettings = { 336 | ALWAYS_SEARCH_USER_PATHS = NO; 337 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 338 | CLANG_CXX_LIBRARY = "libc++"; 339 | CLANG_ENABLE_OBJC_ARC = YES; 340 | CLANG_WARN_EMPTY_BODY = YES; 341 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 342 | COPY_PHASE_STRIP = NO; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_DYNAMIC_NO_PIC = NO; 345 | GCC_OPTIMIZATION_LEVEL = 0; 346 | GCC_PREPROCESSOR_DEFINITIONS = ( 347 | "DEBUG=1", 348 | "$(inherited)", 349 | ); 350 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 351 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 352 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 353 | GCC_WARN_UNUSED_VARIABLE = YES; 354 | INSTALL_PATH = "include/$(PROJECT_NAME)"; 355 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 356 | ONLY_ACTIVE_ARCH = YES; 357 | SDKROOT = iphoneos; 358 | }; 359 | name = Debug; 360 | }; 361 | 09793586161B6251006DB5D5 /* Release */ = { 362 | isa = XCBuildConfiguration; 363 | buildSettings = { 364 | ALWAYS_SEARCH_USER_PATHS = NO; 365 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 366 | CLANG_CXX_LIBRARY = "libc++"; 367 | CLANG_ENABLE_OBJC_ARC = YES; 368 | CLANG_WARN_EMPTY_BODY = YES; 369 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 370 | COPY_PHASE_STRIP = YES; 371 | GCC_C_LANGUAGE_STANDARD = gnu99; 372 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 373 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 374 | GCC_WARN_UNUSED_VARIABLE = YES; 375 | INSTALL_PATH = "include/$(PROJECT_NAME)"; 376 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 377 | SDKROOT = iphoneos; 378 | VALIDATE_PRODUCT = YES; 379 | }; 380 | name = Release; 381 | }; 382 | 09793588161B6251006DB5D5 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 386 | PRODUCT_NAME = "$(TARGET_NAME)"; 387 | SKIP_INSTALL = YES; 388 | }; 389 | name = Debug; 390 | }; 391 | 09793589161B6251006DB5D5 /* Release */ = { 392 | isa = XCBuildConfiguration; 393 | buildSettings = { 394 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 395 | PRODUCT_NAME = "$(TARGET_NAME)"; 396 | SKIP_INSTALL = YES; 397 | }; 398 | name = Release; 399 | }; 400 | 098368DE168FC7920082B1A4 /* Debug */ = { 401 | isa = XCBuildConfiguration; 402 | buildSettings = { 403 | FRAMEWORK_SEARCH_PATHS = ( 404 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 405 | "$(inherited)", 406 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 407 | ); 408 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 409 | GCC_PREFIX_HEADER = "UnitTests/UnitTests-Prefix.pch"; 410 | INFOPLIST_FILE = "UnitTests/UnitTests-Info.plist"; 411 | ONLY_ACTIVE_ARCH = YES; 412 | OTHER_LDFLAGS = ""; 413 | PRODUCT_NAME = "$(TARGET_NAME)"; 414 | }; 415 | name = Debug; 416 | }; 417 | 098368DF168FC7920082B1A4 /* Release */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | FRAMEWORK_SEARCH_PATHS = ( 421 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 422 | "$(inherited)", 423 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 424 | ); 425 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 426 | GCC_PREFIX_HEADER = "UnitTests/UnitTests-Prefix.pch"; 427 | INFOPLIST_FILE = "UnitTests/UnitTests-Info.plist"; 428 | OTHER_LDFLAGS = ""; 429 | PRODUCT_NAME = "$(TARGET_NAME)"; 430 | }; 431 | name = Release; 432 | }; 433 | 53B70031181E9738000FFBD0 /* Test */ = { 434 | isa = XCBuildConfiguration; 435 | buildSettings = { 436 | ALWAYS_SEARCH_USER_PATHS = NO; 437 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 438 | CLANG_CXX_LIBRARY = "libc++"; 439 | CLANG_ENABLE_OBJC_ARC = YES; 440 | CLANG_WARN_EMPTY_BODY = YES; 441 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 442 | COPY_PHASE_STRIP = NO; 443 | GCC_C_LANGUAGE_STANDARD = gnu99; 444 | GCC_DYNAMIC_NO_PIC = NO; 445 | GCC_OPTIMIZATION_LEVEL = 0; 446 | GCC_PREPROCESSOR_DEFINITIONS = ( 447 | "DEBUG=1", 448 | "$(inherited)", 449 | ); 450 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 451 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 452 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 453 | GCC_WARN_UNUSED_VARIABLE = YES; 454 | INSTALL_PATH = "include/$(PROJECT_NAME)"; 455 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 456 | SDKROOT = iphoneos; 457 | }; 458 | name = Test; 459 | }; 460 | 53B70032181E9738000FFBD0 /* Test */ = { 461 | isa = XCBuildConfiguration; 462 | buildSettings = { 463 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 464 | PRODUCT_NAME = "$(TARGET_NAME)"; 465 | SKIP_INSTALL = YES; 466 | }; 467 | name = Test; 468 | }; 469 | 53B70033181E9738000FFBD0 /* Test */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | FRAMEWORK_SEARCH_PATHS = ( 473 | "\"$(SDKROOT)/Developer/Library/Frameworks\"", 474 | "$(inherited)", 475 | "\"$(DEVELOPER_FRAMEWORKS_DIR)\"", 476 | ); 477 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 478 | GCC_PREFIX_HEADER = "UnitTests/UnitTests-Prefix.pch"; 479 | INFOPLIST_FILE = "UnitTests/UnitTests-Info.plist"; 480 | ONLY_ACTIVE_ARCH = YES; 481 | OTHER_LDFLAGS = ""; 482 | PRODUCT_NAME = "$(TARGET_NAME)"; 483 | }; 484 | name = Test; 485 | }; 486 | 53B70034181E9738000FFBD0 /* Test */ = { 487 | isa = XCBuildConfiguration; 488 | buildSettings = { 489 | CLANG_WARN_CONSTANT_CONVERSION = YES; 490 | CLANG_WARN_ENUM_CONVERSION = YES; 491 | CLANG_WARN_INT_CONVERSION = YES; 492 | COMBINE_HIDPI_IMAGES = YES; 493 | DYLIB_COMPATIBILITY_VERSION = 1; 494 | DYLIB_CURRENT_VERSION = 1; 495 | FRAMEWORK_SEARCH_PATHS = ( 496 | "$(inherited)", 497 | "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", 498 | ); 499 | FRAMEWORK_VERSION = A; 500 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 501 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 502 | INFOPLIST_FILE = "OHHTTPStubs-Info.plist"; 503 | MACOSX_DEPLOYMENT_TARGET = 10.7; 504 | ONLY_ACTIVE_ARCH = YES; 505 | PRODUCT_NAME = "$(TARGET_NAME)"; 506 | SDKROOT = macosx; 507 | WRAPPER_EXTENSION = framework; 508 | }; 509 | name = Test; 510 | }; 511 | F6C37BB116F6C8680082B630 /* Debug */ = { 512 | isa = XCBuildConfiguration; 513 | buildSettings = { 514 | CLANG_WARN_CONSTANT_CONVERSION = YES; 515 | CLANG_WARN_ENUM_CONVERSION = YES; 516 | CLANG_WARN_INT_CONVERSION = YES; 517 | COMBINE_HIDPI_IMAGES = YES; 518 | DYLIB_COMPATIBILITY_VERSION = 1; 519 | DYLIB_CURRENT_VERSION = 1; 520 | FRAMEWORK_SEARCH_PATHS = ( 521 | "$(inherited)", 522 | "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", 523 | ); 524 | FRAMEWORK_VERSION = A; 525 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 526 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 527 | INFOPLIST_FILE = "OHHTTPStubs-Info.plist"; 528 | MACOSX_DEPLOYMENT_TARGET = 10.7; 529 | ONLY_ACTIVE_ARCH = YES; 530 | PRODUCT_NAME = "$(TARGET_NAME)"; 531 | SDKROOT = macosx; 532 | WRAPPER_EXTENSION = framework; 533 | }; 534 | name = Debug; 535 | }; 536 | F6C37BB216F6C8680082B630 /* Release */ = { 537 | isa = XCBuildConfiguration; 538 | buildSettings = { 539 | CLANG_WARN_CONSTANT_CONVERSION = YES; 540 | CLANG_WARN_ENUM_CONVERSION = YES; 541 | CLANG_WARN_INT_CONVERSION = YES; 542 | COMBINE_HIDPI_IMAGES = YES; 543 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 544 | DYLIB_COMPATIBILITY_VERSION = 1; 545 | DYLIB_CURRENT_VERSION = 1; 546 | FRAMEWORK_SEARCH_PATHS = ( 547 | "$(inherited)", 548 | "\"$(SYSTEM_APPS_DIR)/Xcode.app/Contents/Developer/Library/Frameworks\"", 549 | ); 550 | FRAMEWORK_VERSION = A; 551 | GCC_ENABLE_OBJC_EXCEPTIONS = YES; 552 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 553 | INFOPLIST_FILE = "OHHTTPStubs-Info.plist"; 554 | MACOSX_DEPLOYMENT_TARGET = 10.7; 555 | PRODUCT_NAME = "$(TARGET_NAME)"; 556 | SDKROOT = macosx; 557 | WRAPPER_EXTENSION = framework; 558 | }; 559 | name = Release; 560 | }; 561 | /* End XCBuildConfiguration section */ 562 | 563 | /* Begin XCConfigurationList section */ 564 | 09793573161B6251006DB5D5 /* Build configuration list for PBXProject "OHHTTPStubs" */ = { 565 | isa = XCConfigurationList; 566 | buildConfigurations = ( 567 | 09793585161B6251006DB5D5 /* Debug */, 568 | 53B70031181E9738000FFBD0 /* Test */, 569 | 09793586161B6251006DB5D5 /* Release */, 570 | ); 571 | defaultConfigurationIsVisible = 0; 572 | defaultConfigurationName = Release; 573 | }; 574 | 09793587161B6251006DB5D5 /* Build configuration list for PBXNativeTarget "OHHTTPStubs-iOS" */ = { 575 | isa = XCConfigurationList; 576 | buildConfigurations = ( 577 | 09793588161B6251006DB5D5 /* Debug */, 578 | 53B70032181E9738000FFBD0 /* Test */, 579 | 09793589161B6251006DB5D5 /* Release */, 580 | ); 581 | defaultConfigurationIsVisible = 0; 582 | defaultConfigurationName = Release; 583 | }; 584 | 098368E0168FC7920082B1A4 /* Build configuration list for PBXNativeTarget "UnitTests" */ = { 585 | isa = XCConfigurationList; 586 | buildConfigurations = ( 587 | 098368DE168FC7920082B1A4 /* Debug */, 588 | 53B70033181E9738000FFBD0 /* Test */, 589 | 098368DF168FC7920082B1A4 /* Release */, 590 | ); 591 | defaultConfigurationIsVisible = 0; 592 | defaultConfigurationName = Release; 593 | }; 594 | F6C37BB316F6C8680082B630 /* Build configuration list for PBXNativeTarget "OHHTTPStubs" */ = { 595 | isa = XCConfigurationList; 596 | buildConfigurations = ( 597 | F6C37BB116F6C8680082B630 /* Debug */, 598 | 53B70034181E9738000FFBD0 /* Test */, 599 | F6C37BB216F6C8680082B630 /* Release */, 600 | ); 601 | defaultConfigurationIsVisible = 0; 602 | defaultConfigurationName = Release; 603 | }; 604 | /* End XCConfigurationList section */ 605 | }; 606 | rootObject = 09793570161B6251006DB5D5 /* Project object */; 607 | } 608 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/xcshareddata/xcschemes/OHHTTPStubs-Mac.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 63 | 64 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/xcshareddata/xcschemes/OHHTTPStubs-iOS.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 60 | 61 | 63 | 64 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubs.xcodeproj/xcshareddata/xcschemes/OHHTTPStubs.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 57 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 76 | 78 | 79 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubsResponse.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | #pragma mark - Defines & Constants 33 | 34 | #define OHHTTPStubsResponseUseStub (OHHTTPStubsResponse*)@"DummyStub" 35 | #define OHHTTPStubsResponseDontUseStub (OHHTTPStubsResponse*)nil 36 | 37 | // Standard download speeds. 38 | extern const double 39 | OHHTTPStubsDownloadSpeedGPRS, 40 | OHHTTPStubsDownloadSpeedEDGE, 41 | OHHTTPStubsDownloadSpeed3G, 42 | OHHTTPStubsDownloadSpeed3GPlus, 43 | OHHTTPStubsDownloadSpeedWifi; 44 | 45 | 46 | //////////////////////////////////////////////////////////////////////////////// 47 | #pragma mark - Interface 48 | 49 | @interface OHHTTPStubsResponse : NSObject 50 | 51 | //////////////////////////////////////////////////////////////////////////////// 52 | #pragma mark - Properties 53 | 54 | @property(nonatomic, retain) NSDictionary* httpHeaders; 55 | @property(nonatomic, assign) int statusCode; 56 | @property(nonatomic, retain) NSData* responseData; 57 | //! @note if responseTime<0, it is interpreted as a download speed in KBps ( -200 => 200KB/s ) 58 | @property(nonatomic, assign) NSTimeInterval responseTime; 59 | @property(nonatomic, retain) NSError* error; 60 | 61 | //////////////////////////////////////////////////////////////////////////////// 62 | #pragma mark - Class Methods 63 | 64 | +(OHHTTPStubsResponse*)responseWithData:(NSData*)data 65 | statusCode:(int)statusCode 66 | responseTime:(NSTimeInterval)responseTime 67 | headers:(NSDictionary*)httpHeaders; 68 | +(OHHTTPStubsResponse*)responseWithFileURL:(NSURL*)fileURL 69 | statusCode:(int)statusCode 70 | responseTime:(NSTimeInterval)responseTime 71 | headers:(NSDictionary*)httpHeaders; 72 | +(OHHTTPStubsResponse*)responseWithFile:(NSString*)fileName 73 | statusCode:(int)statusCode 74 | responseTime:(NSTimeInterval)responseTime 75 | headers:(NSDictionary*)httpHeaders; 76 | +(OHHTTPStubsResponse*)responseWithFile:(NSString*)fileName 77 | contentType:(NSString*)contentType 78 | responseTime:(NSTimeInterval)responseTime; 79 | +(OHHTTPStubsResponse*)responseWithFileURL:(NSURL*)fileURL 80 | contentType:(NSString*)contentType 81 | responseTime:(NSTimeInterval)responseTime; 82 | +(OHHTTPStubsResponse*)responseWithError:(NSError*)error; 83 | 84 | //////////////////////////////////////////////////////////////////////////////// 85 | #pragma mark - Instance Methods 86 | 87 | -(OHHTTPStubsResponse*)initWithData:(NSData*)data 88 | statusCode:(int)statusCode 89 | responseTime:(NSTimeInterval)responseTime 90 | headers:(NSDictionary*)httpHeaders; 91 | -(OHHTTPStubsResponse*)initWithError:(NSError*)error; 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /OHHTTPStubs/OHHTTPStubsResponse.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | #pragma mark - Imports 28 | 29 | #import "OHHTTPStubsResponse.h" 30 | 31 | //////////////////////////////////////////////////////////////////////////////// 32 | #pragma mark - Defines & Constants 33 | 34 | const double OHHTTPStubsDownloadSpeedGPRS =- 56 / 8; // kbps -> KB/s 35 | const double OHHTTPStubsDownloadSpeedEDGE =- 128 / 8; // kbps -> KB/s 36 | const double OHHTTPStubsDownloadSpeed3G =- 3200 / 8; // kbps -> KB/s 37 | const double OHHTTPStubsDownloadSpeed3GPlus =- 7200 / 8; // kbps -> KB/s 38 | const double OHHTTPStubsDownloadSpeedWifi =- 12000 / 8; // kbps -> KB/s 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | #pragma mark - Implementation 42 | 43 | @implementation OHHTTPStubsResponse 44 | 45 | //////////////////////////////////////////////////////////////////////////////// 46 | #pragma mark - Synthesize 47 | 48 | @synthesize httpHeaders = httpHeaders_; 49 | @synthesize statusCode = statusCode_; 50 | @synthesize responseData = responseData_; 51 | @synthesize responseTime = _responseTime; 52 | @synthesize error = error_; 53 | 54 | //////////////////////////////////////////////////////////////////////////////// 55 | #pragma mark - Setup & Teardown 56 | 57 | -(OHHTTPStubsResponse*)initWithData:(NSData*)data 58 | statusCode:(int)statusCode 59 | responseTime:(NSTimeInterval)responseTime 60 | headers:(NSDictionary*)httpHeaders 61 | { 62 | self = [super init]; 63 | if (self) { 64 | self.responseData = data; 65 | self.statusCode = statusCode; 66 | self.httpHeaders = httpHeaders; 67 | self.responseTime = responseTime; 68 | } 69 | return self; 70 | } 71 | 72 | -(OHHTTPStubsResponse*)initWithError:(NSError*)error 73 | { 74 | self = [super init]; 75 | if (self) { 76 | self.error = error; 77 | } 78 | return self; 79 | } 80 | 81 | //////////////////////////////////////////////////////////////////////////////// 82 | #pragma mark - Class Methods 83 | 84 | +(OHHTTPStubsResponse*)responseWithData:(NSData*)data 85 | statusCode:(int)statusCode 86 | responseTime:(NSTimeInterval)responseTime 87 | headers:(NSDictionary*)httpHeaders 88 | { 89 | OHHTTPStubsResponse* response = [[self alloc] initWithData:data 90 | statusCode:statusCode 91 | responseTime:responseTime 92 | headers:httpHeaders]; 93 | return response; 94 | } 95 | 96 | +(OHHTTPStubsResponse*)responseWithFileURL:(NSURL*)fileURL 97 | statusCode:(int)statusCode 98 | responseTime:(NSTimeInterval)responseTime 99 | headers:(NSDictionary*)httpHeaders 100 | { 101 | NSData* data = [NSData dataWithContentsOfURL:fileURL]; 102 | return [self responseWithData:data statusCode:statusCode responseTime:responseTime headers:httpHeaders]; 103 | } 104 | 105 | +(OHHTTPStubsResponse*)responseWithFile:(NSString*)fileName 106 | statusCode:(int)statusCode 107 | responseTime:(NSTimeInterval)responseTime 108 | headers:(NSDictionary*)httpHeaders 109 | { 110 | NSString* basename = [fileName stringByDeletingPathExtension]; 111 | NSString* extension = [fileName pathExtension]; 112 | NSURL* fileURL = [[NSBundle bundleForClass:[self class]] URLForResource:basename withExtension:extension]; 113 | return [self responseWithFileURL:fileURL statusCode:statusCode responseTime:responseTime headers:httpHeaders]; 114 | } 115 | 116 | +(OHHTTPStubsResponse*)responseWithFile:(NSString*)fileName 117 | contentType:(NSString*)contentType 118 | responseTime:(NSTimeInterval)responseTime 119 | { 120 | NSDictionary* headers = [NSDictionary dictionaryWithObject:contentType forKey:@"Content-Type"]; 121 | return [self responseWithFile:fileName statusCode:200 responseTime:responseTime headers:headers]; 122 | } 123 | 124 | +(OHHTTPStubsResponse*)responseWithFileURL:(NSURL*)fileURL 125 | contentType:(NSString*)contentType 126 | responseTime:(NSTimeInterval)responseTime 127 | { 128 | NSDictionary* headers = [NSDictionary dictionaryWithObject:contentType forKey:@"Content-Type"]; 129 | return [self responseWithFileURL:fileURL statusCode:200 responseTime:responseTime headers:headers]; 130 | } 131 | 132 | 133 | +(OHHTTPStubsResponse*)responseWithError:(NSError*)error 134 | { 135 | OHHTTPStubsResponse* response = [[self alloc] initWithError:error]; 136 | return response; 137 | } 138 | 139 | 140 | @end 141 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/AsyncSenTestCase.h: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import 27 | 28 | @interface AsyncSenTestCase : XCTestCase 29 | 30 | @property (strong, nonatomic, readonly) NSOperationQueue *queue; 31 | 32 | /** @note All the waitFor… methods run the current runloop while waiting to let other threads and operations to continue running **/ 33 | -(void)waitForAsyncOperationWithTimeout:(NSTimeInterval)timeout; //!< Wait for one async operation 34 | -(void)waitForAsyncOperations:(NSUInteger)count withTimeout:(NSTimeInterval)timeout; //!< Wait for multiple async operations 35 | -(void)waitForTimeout:(NSTimeInterval)timeout; //!< Wait for a fixed amount of time 36 | -(void)notifyAsyncOperationDone; //!< notify any waiter that the async op is done 37 | @end 38 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/AsyncSenTestCase.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "AsyncSenTestCase.h" 27 | 28 | @interface AsyncSenTestCase() 29 | @property(atomic, assign) NSUInteger asyncTestCaseSignaledCount; 30 | @end 31 | 32 | 33 | 34 | @implementation AsyncSenTestCase 35 | 36 | @synthesize asyncTestCaseSignaledCount = _asyncTestCaseSignaledCount; 37 | 38 | - (void)setUp { 39 | _queue = [[NSOperationQueue alloc] init]; 40 | } 41 | 42 | - (void)tearDown { 43 | _queue = nil; 44 | } 45 | 46 | -(void)waitForAsyncOperationWithTimeout:(NSTimeInterval)timeout 47 | { 48 | [self waitForAsyncOperations:1 withTimeout:timeout]; 49 | } 50 | 51 | -(void)waitForAsyncOperations:(NSUInteger)count withTimeout:(NSTimeInterval)timeout 52 | { 53 | NSDate* timeoutDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; 54 | while ((self.asyncTestCaseSignaledCount < count) && ([timeoutDate timeIntervalSinceNow]>0)) 55 | { 56 | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES); 57 | } 58 | 59 | // Reset the counter for next time, in case we call this method again later 60 | // (don't reset it at the beginning of the method because we should be able to call 61 | // notifyAsyncOperationDone *before* this method if we wanted to) 62 | self.asyncTestCaseSignaledCount = 0; 63 | 64 | if ([timeoutDate timeIntervalSinceNow]<0) 65 | { 66 | // now is after timeoutDate, we timed out 67 | XCTFail(@"Timed out while waiting for Async Operations to finish."); 68 | } 69 | } 70 | 71 | -(void)waitForTimeout:(NSTimeInterval)timeout 72 | { 73 | NSDate* waitEndDate = [NSDate dateWithTimeIntervalSinceNow:timeout]; 74 | while ([waitEndDate timeIntervalSinceNow]>0) 75 | { 76 | CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, YES); 77 | } 78 | } 79 | 80 | -(void)notifyAsyncOperationDone 81 | { 82 | @synchronized(self) 83 | { 84 | self.asyncTestCaseSignaledCount = self.asyncTestCaseSignaledCount+1; 85 | } 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/Test Suites/NSURLConnectionDelegateTests.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "AsyncSenTestCase.h" 27 | #import "OHHTTPStubs.h" 28 | 29 | @interface NSURLConnectionDelegateTests : AsyncSenTestCase @end 30 | 31 | static const NSTimeInterval kResponseTimeTolerence = 0.2; 32 | 33 | @implementation NSURLConnectionDelegateTests 34 | { 35 | NSMutableData* _data; 36 | NSError* _error; 37 | } 38 | 39 | /////////////////////////////////////////////////////////////////////////////////// 40 | #pragma mark Global Setup + NSURLConnectionDelegate implementation 41 | /////////////////////////////////////////////////////////////////////////////////// 42 | 43 | -(void)setUp 44 | { 45 | [super setUp]; 46 | _data = [[NSMutableData alloc] init]; 47 | } 48 | 49 | -(void)tearDown 50 | { 51 | // in case the test timed out and finished before a running NSURLConnection ended, 52 | // we may continue receive delegate messages anyway if we forgot to cancel. 53 | // So avoid sending messages to deallocated object in this case by ensuring we reset it to nil 54 | _data = nil; 55 | _error = nil; 56 | [super tearDown]; 57 | } 58 | 59 | -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 60 | { 61 | [_data setLength:0U]; 62 | } 63 | 64 | -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 65 | { 66 | [_data appendData:data]; 67 | } 68 | 69 | -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 70 | { 71 | _error = error; 72 | [self notifyAsyncOperationDone]; 73 | } 74 | 75 | -(void)connectionDidFinishLoading:(NSURLConnection *)connection 76 | { 77 | [self notifyAsyncOperationDone]; 78 | } 79 | 80 | 81 | 82 | /////////////////////////////////////////////////////////////////////////////////// 83 | #pragma mark NSURLConnection + Delegate 84 | /////////////////////////////////////////////////////////////////////////////////// 85 | 86 | -(void)test_NSURLConnectionDelegate_success 87 | { 88 | static const NSTimeInterval kResponseTime = 1.0; 89 | NSData* testData = [NSStringFromSelector(_cmd) dataUsingEncoding:NSUTF8StringEncoding]; 90 | 91 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 92 | return YES; 93 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 94 | return [OHHTTPStubsResponse responseWithData:testData 95 | statusCode:200 96 | responseTime:kResponseTime 97 | headers:nil]; 98 | }]; 99 | 100 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 101 | NSDate* startDate = [NSDate date]; 102 | 103 | NSURLConnection* cxn = [NSURLConnection connectionWithRequest:req delegate:self]; 104 | 105 | [self waitForAsyncOperationWithTimeout:kResponseTime+kResponseTimeTolerence]; 106 | 107 | XCTAssertEqualObjects(_data, testData, @"Invalid data response"); 108 | XCTAssertNil(_error, @"Received unexpected network error %@", _error); 109 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 110 | 111 | // in case we timed out before the end of the request (test failed), cancel the request to avoid further delegate method calls 112 | [cxn cancel]; 113 | } 114 | 115 | -(void)test_NSURLConnectionDelegate_error 116 | { 117 | static const NSTimeInterval kResponseTime = 1.0; 118 | NSError* expectedError = [NSError errorWithDomain:NSURLErrorDomain code:404 userInfo:nil]; 119 | 120 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 121 | return YES; 122 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 123 | OHHTTPStubsResponse* resp = [OHHTTPStubsResponse responseWithError:expectedError]; 124 | resp.responseTime = kResponseTime; 125 | return resp; 126 | }]; 127 | 128 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 129 | NSDate* startDate = [NSDate date]; 130 | 131 | NSURLConnection* cxn = [NSURLConnection connectionWithRequest:req delegate:self]; 132 | 133 | [self waitForAsyncOperationWithTimeout:kResponseTime+kResponseTimeTolerence]; 134 | 135 | XCTAssertEqual(_data.length, 0U, @"Received unexpected network data %@", _data); 136 | XCTAssertEqualObjects(_error.domain, expectedError.domain, @"Invalid error response domain"); 137 | XCTAssertEqual(_error.code, expectedError.code, @"Invalid error response code"); 138 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 139 | 140 | // in case we timed out before the end of the request (test failed), cancel the request to avoid further delegate method calls 141 | [cxn cancel]; 142 | } 143 | 144 | 145 | /////////////////////////////////////////////////////////////////////////////////// 146 | #pragma mark Cancelling requests 147 | /////////////////////////////////////////////////////////////////////////////////// 148 | 149 | -(void)test_NSURLConnection_cancel 150 | { 151 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 152 | return YES; 153 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 154 | return [OHHTTPStubsResponse responseWithData:[@"" dataUsingEncoding:NSUTF8StringEncoding] 155 | statusCode:500 156 | responseTime:1.5 157 | headers:nil]; 158 | }]; 159 | 160 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 161 | NSURLConnection* cxn = [NSURLConnection connectionWithRequest:req delegate:self]; 162 | 163 | [self waitForTimeout:0.5]; 164 | [cxn cancel]; 165 | [self waitForTimeout:1.5]; 166 | 167 | XCTAssertEqual(_data.length, 0U, @"Received unexpected data but the request should have been cancelled"); 168 | XCTAssertNil(_error, @"Received unexpected network error but the request should have been cancelled"); 169 | 170 | // in case we timed out before the end of the request (test failed), cancel the request to avoid further delegate method calls 171 | [cxn cancel]; 172 | } 173 | 174 | 175 | /////////////////////////////////////////////////////////////////////////////////// 176 | #pragma mark Cancelling requests 177 | /////////////////////////////////////////////////////////////////////////////////// 178 | 179 | -(void)test_NSURLConnection_cookies 180 | { 181 | NSString* const cookieName = @"SESSIONID"; 182 | NSString* const cookieValue = [[NSProcessInfo processInfo] globallyUniqueString]; 183 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 184 | return YES; 185 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 186 | NSString* cookie = [NSString stringWithFormat:@"%@=%@;", cookieName, cookieValue]; 187 | NSDictionary* headers = [NSDictionary dictionaryWithObject:cookie forKey:@"Set-Cookie"]; 188 | return [OHHTTPStubsResponse responseWithData:[@"Yummy cookies" dataUsingEncoding:NSUTF8StringEncoding] 189 | statusCode:200 190 | responseTime:0 191 | headers:headers]; 192 | }]; 193 | 194 | // Set the cookie accept policy to accept all cookies from the main document domain 195 | // (especially in case the previous policy was "NSHTTPCookieAcceptPolicyNever") 196 | NSHTTPCookieStorage* cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage]; 197 | NSHTTPCookieAcceptPolicy previousAcceptPolicy = [cookieStorage cookieAcceptPolicy]; // keep it to restore later 198 | [cookieStorage setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain]; 199 | 200 | // Send the request and wait for the response containing the Set-Cookie headers 201 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 202 | NSURLConnection* cxn = [NSURLConnection connectionWithRequest:req delegate:self]; 203 | [self waitForAsyncOperationWithTimeout:kResponseTimeTolerence]; 204 | [cxn cancel]; // In case we timed out (test failed), cancel the request to avoid further delegate method calls 205 | 206 | 207 | /* Check that the cookie has been properly stored */ 208 | NSArray* cookies = [cookieStorage cookiesForURL:req.URL]; 209 | BOOL cookieFound = NO; 210 | for (NSHTTPCookie* cookie in cookies) 211 | { 212 | if ([cookie.name isEqualToString:cookieName]) 213 | { 214 | cookieFound = YES; 215 | XCTAssertEqualObjects(cookie.value, cookieValue, @"The cookie does not have the expected value"); 216 | } 217 | } 218 | XCTAssertTrue(cookieFound, @"The cookie was not stored as expected"); 219 | 220 | 221 | // As a courtesy, restore previous policy before leaving 222 | [cookieStorage setCookieAcceptPolicy:previousAcceptPolicy]; 223 | 224 | } 225 | 226 | @end 227 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/Test Suites/NSURLConnectionTests.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "AsyncSenTestCase.h" 27 | #import "OHHTTPStubs.h" 28 | 29 | @interface NSURLConnectionTests : AsyncSenTestCase @end 30 | 31 | static const NSTimeInterval kResponseTimeTolerence = 0.2; 32 | 33 | @implementation NSURLConnectionTests 34 | 35 | 36 | /////////////////////////////////////////////////////////////////////////////////// 37 | #pragma mark [NSURLConnection sendSynchronousRequest:returningResponse:error:] 38 | /////////////////////////////////////////////////////////////////////////////////// 39 | 40 | -(void)test_NSURLConnection_sendSyncronousRequest_mainQueue 41 | { 42 | static const NSTimeInterval kResponseTime = 1.0; 43 | NSData* testData = [NSStringFromSelector(_cmd) dataUsingEncoding:NSUTF8StringEncoding]; 44 | 45 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 46 | return YES; 47 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 48 | return [OHHTTPStubsResponse responseWithData:testData 49 | statusCode:200 50 | responseTime:kResponseTime 51 | headers:nil]; 52 | }]; 53 | 54 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 55 | NSDate* startDate = [NSDate date]; 56 | 57 | NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:NULL error:NULL]; 58 | 59 | XCTAssertEqualObjects(data, testData, @"Invalid data response"); 60 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 61 | } 62 | 63 | -(void)test_NSURLConnection_sendSyncronousRequest_parallelQueue 64 | { 65 | [self.queue addOperationWithBlock:^{ 66 | [self test_NSURLConnection_sendSyncronousRequest_mainQueue]; 67 | [self notifyAsyncOperationDone]; 68 | }]; 69 | [self waitForAsyncOperationWithTimeout:3.0]; 70 | } 71 | 72 | /////////////////////////////////////////////////////////////////////////////////// 73 | #pragma mark Single [NSURLConnection sendAsynchronousRequest:queue:completionHandler:] 74 | /////////////////////////////////////////////////////////////////////////////////// 75 | 76 | -(void)_test_NSURLConnection_sendAsyncronousRequest_onOperationQueue:(NSOperationQueue*)queue 77 | { 78 | static const NSTimeInterval kResponseTime = 1.0; 79 | NSData* testData = [NSStringFromSelector(_cmd) dataUsingEncoding:NSUTF8StringEncoding]; 80 | 81 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 82 | return YES; 83 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 84 | return [OHHTTPStubsResponse responseWithData:testData 85 | statusCode:200 86 | responseTime:kResponseTime 87 | headers:nil]; 88 | }]; 89 | 90 | 91 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 92 | NSDate* startDate = [NSDate date]; 93 | 94 | [NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error) 95 | { 96 | XCTAssertEqualObjects(data, testData, @"Invalid data response"); 97 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 98 | 99 | [self notifyAsyncOperationDone]; 100 | }]; 101 | 102 | [self waitForAsyncOperationWithTimeout:kResponseTime+kResponseTimeTolerence]; 103 | } 104 | 105 | 106 | -(void)test_NSURLConnection_sendAsyncronousRequest_mainQueue 107 | { 108 | [self _test_NSURLConnection_sendAsyncronousRequest_onOperationQueue:[NSOperationQueue mainQueue]]; 109 | } 110 | 111 | 112 | -(void)test_NSURLConnection_sendAsyncronousRequest_parallelQueue 113 | { 114 | [self _test_NSURLConnection_sendAsyncronousRequest_onOperationQueue:self.queue]; 115 | } 116 | 117 | 118 | /////////////////////////////////////////////////////////////////////////////////// 119 | #pragma mark Multiple Parallel [NSURLConnection sendAsynchronousRequest:queue:completionHandler:] 120 | /////////////////////////////////////////////////////////////////////////////////// 121 | 122 | -(void)_test_NSURLConnection_sendMultipleAsyncronousRequestsOnOperationQueue:(NSOperationQueue*)queue 123 | { 124 | NSData* (^dataForRequest)(NSURLRequest*) = ^(NSURLRequest* req) { 125 | return [[NSString stringWithFormat:@"",req.URL.absoluteString] dataUsingEncoding:NSUTF8StringEncoding]; 126 | }; 127 | 128 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 129 | return YES; 130 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 131 | NSData* retData = dataForRequest(request); 132 | NSTimeInterval responseTime = [request.URL.lastPathComponent doubleValue]; 133 | return [OHHTTPStubsResponse responseWithData:retData 134 | statusCode:200 135 | responseTime:responseTime 136 | headers:nil]; 137 | }]; 138 | 139 | // Reusable code to send a request that will respond in the given response time 140 | void (^sendAsyncRequest)(NSTimeInterval) = ^(NSTimeInterval responseTime) 141 | { 142 | NSString* urlString = [NSString stringWithFormat:@"http://dummyrequest/concurrent/time/%f",responseTime]; 143 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 144 | XCTestLog *testLog = [[XCTestLog alloc] init]; 145 | [testLog testLogWithFormat:@"== Sending request %@\n", req]; 146 | NSDate* startDate = [NSDate date]; 147 | [NSURLConnection sendAsynchronousRequest:req queue:queue completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error) 148 | { 149 | [testLog testLogWithFormat:@"== Received response for request %@\n", req]; 150 | XCTAssertEqualObjects(data, dataForRequest(req), @"Invalid data response"); 151 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], responseTime, kResponseTimeTolerence, @"Invalid response time"); 152 | 153 | [self notifyAsyncOperationDone]; 154 | }]; 155 | }; 156 | 157 | sendAsyncRequest(1.5); // send this one first, should receive last 158 | sendAsyncRequest(1.0); // send this one next, shoud receive 2nd 159 | sendAsyncRequest(0.5); // send this one last, should receive first 160 | 161 | [self waitForAsyncOperations:3 withTimeout:4.0]; // time out after 4s because the requests should run concurrently and all should be done in ~1.5s 162 | } 163 | 164 | -(void)test_NSURLConnection_sendMultipleAsyncronousRequests_mainQueue 165 | { 166 | [self _test_NSURLConnection_sendMultipleAsyncronousRequestsOnOperationQueue:[NSOperationQueue mainQueue]]; 167 | } 168 | 169 | -(void)test_NSURLConnection_sendMultipleAsyncronousRequests_parallelQueue 170 | { 171 | [self _test_NSURLConnection_sendMultipleAsyncronousRequestsOnOperationQueue:self.queue]; 172 | } 173 | 174 | @end 175 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/Test Suites/WithContentsOfURLTests.m: -------------------------------------------------------------------------------- 1 | /*********************************************************************************** 2 | * 3 | * Copyright (c) 2012 Olivier Halligon 4 | * 5 | * Permission is hereby granted, free of charge, to any person obtaining a copy 6 | * of this software and associated documentation files (the "Software"), to deal 7 | * in the Software without restriction, including without limitation the rights 8 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | * copies of the Software, and to permit persons to whom the Software is 10 | * furnished to do so, subject to the following conditions: 11 | * 12 | * The above copyright notice and this permission notice shall be included in 13 | * all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | * THE SOFTWARE. 22 | * 23 | ***********************************************************************************/ 24 | 25 | 26 | #import "AsyncSenTestCase.h" 27 | #import "OHHTTPStubs.h" 28 | 29 | @interface WithContentsOfURLTests : AsyncSenTestCase @end 30 | 31 | static const NSTimeInterval kResponseTimeTolerence = 0.2; 32 | 33 | @implementation WithContentsOfURLTests 34 | 35 | 36 | 37 | 38 | /////////////////////////////////////////////////////////////////////////////////// 39 | #pragma mark [NSString stringWithContentsOfURL:encoding:error:] 40 | /////////////////////////////////////////////////////////////////////////////////// 41 | 42 | -(void)test_NSString_stringWithContentsOfURL_mainQueue 43 | { 44 | static const NSTimeInterval kResponseTime = 1.0; 45 | NSString* testString = NSStringFromSelector(_cmd); 46 | 47 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 48 | return YES; 49 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 50 | return [OHHTTPStubsResponse responseWithData:[testString dataUsingEncoding:NSUTF8StringEncoding] 51 | statusCode:200 52 | responseTime:kResponseTime 53 | headers:nil]; 54 | }]; 55 | 56 | NSDate* startDate = [NSDate date]; 57 | 58 | NSString* string = [NSString stringWithContentsOfURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"] 59 | encoding:NSUTF8StringEncoding 60 | error:NULL]; 61 | 62 | XCTAssertEqualObjects(string, testString, @"Invalid returned string"); 63 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 64 | } 65 | 66 | -(void)test_NSString_stringWithContentsOfURL_parallelQueue 67 | { 68 | [self.queue addOperationWithBlock:^{ 69 | [self test_NSString_stringWithContentsOfURL_mainQueue]; 70 | [self notifyAsyncOperationDone]; 71 | }]; 72 | [self waitForAsyncOperationWithTimeout:3.0]; 73 | } 74 | 75 | /////////////////////////////////////////////////////////////////////////////////// 76 | #pragma mark [NSData dataWithContentsOfURL:] 77 | /////////////////////////////////////////////////////////////////////////////////// 78 | 79 | -(void)test_NSData_dataWithContentsOfURL_mainQueue 80 | { 81 | static const NSTimeInterval kResponseTime = 1.0; 82 | NSData* testData = [NSStringFromSelector(_cmd) dataUsingEncoding:NSUTF8StringEncoding]; 83 | 84 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 85 | return YES; 86 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 87 | return [OHHTTPStubsResponse responseWithData:testData 88 | statusCode:200 89 | responseTime:kResponseTime 90 | headers:nil]; 91 | }]; 92 | 93 | NSDate* startDate = [NSDate date]; 94 | 95 | NSData* data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://www.iana.org/domains/example/"]]; 96 | 97 | XCTAssertEqualObjects(data, testData, @"Invalid returned string"); 98 | XCTAssertEqualWithAccuracy(-[startDate timeIntervalSinceNow], kResponseTime, kResponseTimeTolerence, @"Invalid response time"); 99 | } 100 | 101 | -(void)test_NSData_dataWithContentsOfURL_parallelQueue 102 | { 103 | [self.queue addOperationWithBlock:^{ 104 | [self test_NSData_dataWithContentsOfURL_mainQueue]; 105 | [self notifyAsyncOperationDone]; 106 | }]; 107 | [self waitForAsyncOperationWithTimeout:3.0]; 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/UnitTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.alisoftware.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /OHHTTPStubs/UnitTests/UnitTests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'OHHTTPStubs Unit Tests' target in the 'OHHTTPStubs Unit Tests' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #endif 8 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/OHHTTPStubs/8761af63dc87ef8dd3944f2248ac4e1f6256c4c8/OHHTTPStubsDemo/Default-568h@2x.png -------------------------------------------------------------------------------- /OHHTTPStubsDemo/MainViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.h 3 | // OHHTTPStubsDemo 4 | // 5 | // Created by Olivier Halligon on 11/08/12. 6 | // Copyright (c) 2012 AliSoftware. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MainViewController : UIViewController 12 | - (IBAction)toggleStubs:(UISwitch*)sender; 13 | - (IBAction)downloadText:(UIButton*)sender; 14 | - (IBAction)installTextStub:(UISwitch*)sender; 15 | - (IBAction)downloadImage:(UIButton*)sender; 16 | - (IBAction)installImageStub:(UISwitch*)sender; 17 | - (IBAction)clearResults; 18 | 19 | @property (retain, nonatomic) IBOutlet UISwitch *delaySwitch; 20 | @property (retain, nonatomic) IBOutlet UITextView *textView; 21 | @property (retain, nonatomic) IBOutlet UISwitch *installTextStubSwitch; 22 | @property (retain, nonatomic) IBOutlet UIImageView *imageView; 23 | @property (retain, nonatomic) IBOutlet UISwitch *installImageStubSwitch; 24 | @end 25 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/MainViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MainViewController.m 3 | // OHHTTPStubsDemo 4 | // 5 | // Created by Olivier Halligon on 11/08/12. 6 | // Copyright (c) 2012 AliSoftware. All rights reserved. 7 | // 8 | 9 | #import "MainViewController.h" 10 | #import 11 | 12 | 13 | @implementation MainViewController 14 | // IBOutlets 15 | @synthesize delaySwitch = _delaySwitch; 16 | @synthesize textView = _textView; 17 | @synthesize installTextStubSwitch = _installTextStubSwitch; 18 | @synthesize installImageStubSwitch = _installImageStubSwitch; 19 | @synthesize imageView = _imageView; 20 | 21 | 22 | //////////////////////////////////////////////////////////////////////////////// 23 | #pragma mark - Init & Dealloc 24 | 25 | - (void)dealloc 26 | { 27 | #if ! __has_feature(objc_arc) 28 | [_textView release]; 29 | [_imageView release]; 30 | [_delaySwitch release]; 31 | [_installTextStubSwitch release]; 32 | [_installImageStubSwitch release]; 33 | [super dealloc]; 34 | #endif 35 | } 36 | 37 | - (void)viewDidLoad 38 | { 39 | [super viewDidLoad]; 40 | 41 | [self installTextStub:self.installTextStubSwitch]; 42 | [self installImageStub:self.installImageStubSwitch]; 43 | } 44 | - (void)viewDidUnload 45 | { 46 | [self setTextView:nil]; 47 | [self setImageView:nil]; 48 | [self setDelaySwitch:nil]; 49 | [super viewDidUnload]; 50 | } 51 | 52 | //////////////////////////////////////////////////////////////////////////////// 53 | #pragma mark - Global stubs activation 54 | 55 | - (IBAction)toggleStubs:(UISwitch *)sender 56 | { 57 | [OHHTTPStubs setEnabled:sender.on]; 58 | self.delaySwitch.enabled = sender.on; 59 | self.installTextStubSwitch.enabled = sender.on; 60 | self.installImageStubSwitch.enabled = sender.on; 61 | } 62 | 63 | 64 | 65 | 66 | //////////////////////////////////////////////////////////////////////////////// 67 | #pragma mark - Text Download and Stub 68 | 69 | 70 | - (IBAction)downloadText:(UIButton*)sender 71 | { 72 | sender.enabled = NO; 73 | 74 | NSString* urlString = @"http://www.loremipsum.de/downloads/version3.txt"; 75 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 76 | 77 | // This is a very handy way to send an asynchronous method, but only available in iOS5+ 78 | [NSURLConnection sendAsynchronousRequest:req 79 | queue:[NSOperationQueue mainQueue] 80 | completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error) 81 | { 82 | sender.enabled = YES; 83 | NSString* receivedText = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; 84 | self.textView.text = receivedText; 85 | #if ! __has_feature(objc_arc) 86 | [receivedText release]; 87 | #endif 88 | }]; 89 | } 90 | 91 | 92 | 93 | 94 | - (IBAction)installTextStub:(UISwitch *)sender 95 | { 96 | static id textHandler = nil; // Note: no need to retain this value, it is retained by the OHHTTPStubs itself already :) 97 | 98 | if (sender.on) 99 | { 100 | // Install 101 | textHandler = [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 102 | // This handler will only configure stub requests for "*.txt" files 103 | return [request.URL.absoluteString.pathExtension isEqualToString:@"txt"]; 104 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 105 | // Stub txt files with this 106 | return [OHHTTPStubsResponse responseWithFile:@"stub.txt" 107 | contentType:@"text/plain" 108 | responseTime:self.delaySwitch.on ? 2.f: 0.f]; 109 | }]; 110 | } 111 | else 112 | { 113 | // Uninstall 114 | [OHHTTPStubs removeRequestHandler:textHandler]; 115 | } 116 | } 117 | 118 | 119 | //////////////////////////////////////////////////////////////////////////////// 120 | #pragma mark - Image Download and Stub 121 | 122 | - (IBAction)downloadImage:(UIButton*)sender 123 | { 124 | sender.enabled = NO; 125 | 126 | NSString* urlString = @"http://images.apple.com/iphone/ios/images/ios_business_2x.jpg"; 127 | NSURLRequest* req = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]]; 128 | 129 | // This is a very handy way to send an asynchronous method, but only available in iOS5+ 130 | [NSURLConnection sendAsynchronousRequest:req 131 | queue:[NSOperationQueue mainQueue] 132 | completionHandler:^(NSURLResponse* resp, NSData* data, NSError* error) 133 | { 134 | sender.enabled = YES; 135 | self.imageView.image = [UIImage imageWithData:data]; 136 | }]; 137 | } 138 | 139 | - (IBAction)installImageStub:(UISwitch *)sender 140 | { 141 | static id imageHandler = nil; // Note: no need to retain this value, it is retained by the OHHTTPStubs itself already :) 142 | if (sender.on) 143 | { 144 | // Install 145 | imageHandler = [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 146 | // This handler will only configure stub requests for "*.jpg" files 147 | return [request.URL.absoluteString.pathExtension isEqualToString:@"jpg"]; 148 | } withStubResponse:^OHHTTPStubsResponse *(NSURLRequest *request) { 149 | // Stub jpg files with this 150 | return [OHHTTPStubsResponse responseWithFile:@"stub.jpg" 151 | contentType:@"image/jpeg" 152 | responseTime:self.delaySwitch.on ? 2.f: 0.f]; 153 | }]; 154 | } 155 | else 156 | { 157 | // Uninstall 158 | [OHHTTPStubs removeRequestHandler:imageHandler]; 159 | } 160 | } 161 | 162 | //////////////////////////////////////////////////////////////////////////////// 163 | #pragma mark - Cleaning 164 | 165 | - (IBAction)clearResults 166 | { 167 | self.textView.text = @""; 168 | self.imageView.image = nil; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/MainViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1296 5 | 11E53 6 | 2549 7 | 1138.47 8 | 569.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1498 12 | 13 | 14 | IBProxyObject 15 | IBUIButton 16 | IBUIImageView 17 | IBUILabel 18 | IBUISwitch 19 | IBUITextView 20 | IBUIView 21 | IBUIViewController 22 | IBUIWindow 23 | 24 | 25 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 26 | 27 | 28 | PluginDependencyRecalculationVersion 29 | 30 | 31 | 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | 42 | 292 43 | {320, 480} 44 | 45 | _NS:9 46 | 47 | 1 48 | MSAxIDEAA 49 | 50 | NO 51 | NO 52 | 53 | IBCocoaTouchFramework 54 | YES 55 | YES 56 | 57 | 58 | 59 | 60 | 274 61 | 62 | 63 | 64 | 292 65 | {{20, 110}, {176, 37}} 66 | 67 | 68 | 69 | _NS:9 70 | NO 71 | IBCocoaTouchFramework 72 | 0 73 | 0 74 | 1 75 | Downloading… 76 | Download some text 77 | 78 | 3 79 | MQA 80 | 81 | 82 | 3 83 | MC42NjY2NjY2NjY3AA 84 | 85 | 86 | 1 87 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 88 | 89 | 90 | 3 91 | MC41AA 92 | 93 | 94 | 2 95 | 15 96 | 97 | 98 | Helvetica-Bold 99 | 15 100 | 16 101 | 102 | 103 | 104 | 105 | 292 106 | {{206, 17}, {94, 27}} 107 | 108 | 109 | 110 | _NS:9 111 | NO 112 | IBCocoaTouchFramework 113 | 0 114 | 0 115 | YES 116 | 117 | 118 | 119 | 292 120 | {{20, 155}, {280, 92}} 121 | 122 | 123 | 124 | _NS:9 125 | 126 | YES 127 | YES 128 | IBCocoaTouchFramework 129 | NO 130 | 131 | 132 | 2 133 | IBCocoaTouchFramework 134 | 135 | 136 | 1 137 | 14 138 | 139 | 140 | Helvetica 141 | 14 142 | 16 143 | 144 | 145 | 146 | 147 | 292 148 | {{20, 20}, {177, 21}} 149 | 150 | 151 | 152 | _NS:9 153 | NO 154 | YES 155 | 7 156 | NO 157 | IBCocoaTouchFramework 158 | Activate Stubs Globally 159 | 160 | 1 161 | MCAwIDAAA 162 | 163 | 164 | 0 165 | 10 166 | 167 | 1 168 | 17 169 | 170 | 171 | Helvetica 172 | 17 173 | 16 174 | 175 | 176 | 177 | 178 | 292 179 | {{20, 255}, {176, 37}} 180 | 181 | 182 | 183 | _NS:9 184 | NO 185 | IBCocoaTouchFramework 186 | 0 187 | 0 188 | 1 189 | Downloading… 190 | Download image 191 | 192 | 193 | 194 | 1 195 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 292 204 | {{20, 300}, {280, 140}} 205 | 206 | 207 | 208 | _NS:9 209 | 1 210 | NO 211 | IBCocoaTouchFramework 212 | 213 | 214 | 215 | 292 216 | {{20, 55}, {109, 21}} 217 | 218 | 219 | 220 | _NS:9 221 | NO 222 | YES 223 | 7 224 | NO 225 | IBCocoaTouchFramework 226 | Fake 2s Delay 227 | 228 | 229 | 0 230 | 10 231 | 232 | 233 | 234 | 235 | 236 | 292 237 | {{129, 52}, {94, 27}} 238 | 239 | 240 | 241 | _NS:9 242 | NO 243 | IBCocoaTouchFramework 244 | 0 245 | 0 246 | 247 | 248 | 249 | 292 250 | {{231, 49}, {69, 35}} 251 | 252 | 253 | 254 | _NS:9 255 | NO 256 | IBCocoaTouchFramework 257 | 0 258 | 0 259 | 1 260 | Clear 261 | 262 | 263 | 1 264 | MC4xOTYwNzg0MzQ2IDAuMzA5ODAzOTMyOSAwLjUyMTU2ODY1NgA 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 292 273 | {{206, 120}, {94, 27}} 274 | 275 | 276 | 277 | _NS:9 278 | NO 279 | IBCocoaTouchFramework 280 | 0 281 | 0 282 | YES 283 | 284 | 285 | 286 | 292 287 | {{206, 265}, {94, 27}} 288 | 289 | 290 | 291 | _NS:9 292 | NO 293 | IBCocoaTouchFramework 294 | 0 295 | 0 296 | YES 297 | 298 | 299 | 300 | 292 301 | {{221, 100}, {79, 21}} 302 | 303 | 304 | 305 | _NS:9 306 | NO 307 | YES 308 | 7 309 | NO 310 | IBCocoaTouchFramework 311 | Stub installed? 312 | 313 | 314 | 0 315 | 10 316 | 1 317 | 318 | 1 319 | 9 320 | 321 | 322 | Helvetica 323 | 9 324 | 16 325 | 326 | NO 327 | 328 | 329 | 330 | 292 331 | {{221, 245}, {79, 21}} 332 | 333 | 334 | 335 | _NS:9 336 | NO 337 | YES 338 | 7 339 | NO 340 | IBCocoaTouchFramework 341 | Stub installed? 342 | 343 | 344 | 0 345 | 10 346 | 1 347 | 348 | 349 | NO 350 | 351 | 352 | {{0, 20}, {320, 460}} 353 | 354 | 355 | 356 | 357 | 3 358 | MQA 359 | 360 | 2 361 | 362 | 363 | 364 | IBCocoaTouchFramework 365 | 366 | 367 | 368 | 1 369 | 1 370 | 371 | IBCocoaTouchFramework 372 | NO 373 | 374 | 375 | 376 | 377 | 378 | 379 | downloadText: 380 | 381 | 382 | 7 383 | 384 | 32 385 | 386 | 387 | 388 | toggleStubs: 389 | 390 | 391 | 13 392 | 393 | 23 394 | 395 | 396 | 397 | downloadImage: 398 | 399 | 400 | 7 401 | 402 | 33 403 | 404 | 405 | 406 | rootViewController 407 | 408 | 409 | 410 | 22 411 | 412 | 413 | 414 | textView 415 | 416 | 417 | 418 | 24 419 | 420 | 421 | 422 | imageView 423 | 424 | 425 | 426 | 25 427 | 428 | 429 | 430 | delaySwitch 431 | 432 | 433 | 434 | 26 435 | 436 | 437 | 438 | installTextStubSwitch 439 | 440 | 441 | 442 | 47 443 | 444 | 445 | 446 | installImageStubSwitch 447 | 448 | 449 | 450 | 48 451 | 452 | 453 | 454 | clearResults 455 | 456 | 457 | 7 458 | 459 | 31 460 | 461 | 462 | 463 | installTextStub: 464 | 465 | 466 | 13 467 | 468 | 45 469 | 470 | 471 | 472 | installImageStub: 473 | 474 | 475 | 13 476 | 477 | 46 478 | 479 | 480 | 481 | 482 | 483 | 0 484 | 485 | 486 | 487 | 488 | 489 | -1 490 | 491 | 492 | File's Owner 493 | 494 | 495 | -2 496 | 497 | 498 | 499 | 500 | 20 501 | 502 | 503 | 504 | 505 | 21 506 | 507 | 508 | 509 | 510 | 511 | 512 | 513 | 1 514 | 515 | 516 | 517 | 518 | 519 | 520 | 521 | 522 | 523 | 524 | 525 | 526 | 527 | 528 | 529 | 530 | 531 | 532 | 533 | 17 534 | 535 | 536 | 537 | 538 | 15 539 | 540 | 541 | 542 | 543 | 5 544 | 545 | 546 | 547 | 548 | 9 549 | 550 | 551 | 552 | 553 | 8 554 | 555 | 556 | 557 | 558 | 6 559 | 560 | 561 | 562 | 563 | 4 564 | 565 | 566 | 567 | 568 | 7 569 | 570 | 571 | 572 | 573 | 29 574 | 575 | 576 | 577 | 578 | 41 579 | 580 | 581 | 582 | 583 | 42 584 | 585 | 586 | 587 | 588 | 43 589 | 590 | 591 | 592 | 593 | 44 594 | 595 | 596 | 597 | 598 | 599 | 600 | UIApplication 601 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 602 | UIResponder 603 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 604 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 605 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 606 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 607 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 608 | MainViewController 609 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 610 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 611 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 612 | 613 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 614 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 615 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 616 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 617 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 618 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 619 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 620 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 621 | 622 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 623 | 624 | 625 | 626 | 627 | 628 | 48 629 | 630 | 631 | 632 | 633 | MainViewController 634 | UIViewController 635 | 636 | id 637 | UIButton 638 | UIButton 639 | UISwitch 640 | UISwitch 641 | UISwitch 642 | 643 | 644 | 645 | clearResults 646 | id 647 | 648 | 649 | downloadImage: 650 | UIButton 651 | 652 | 653 | downloadText: 654 | UIButton 655 | 656 | 657 | installImageStub: 658 | UISwitch 659 | 660 | 661 | installTextStub: 662 | UISwitch 663 | 664 | 665 | toggleStubs: 666 | UISwitch 667 | 668 | 669 | 670 | UISwitch 671 | UIImageView 672 | UIButton 673 | UISwitch 674 | UIButton 675 | UISwitch 676 | UITextView 677 | 678 | 679 | 680 | delaySwitch 681 | UISwitch 682 | 683 | 684 | imageView 685 | UIImageView 686 | 687 | 688 | installImageStubButton 689 | UIButton 690 | 691 | 692 | installImageStubSwitch 693 | UISwitch 694 | 695 | 696 | installTextStubButton 697 | UIButton 698 | 699 | 700 | installTextStubSwitch 701 | UISwitch 702 | 703 | 704 | textView 705 | UITextView 706 | 707 | 708 | 709 | IBProjectSource 710 | ./Classes/MainViewController.h 711 | 712 | 713 | 714 | 715 | 0 716 | IBCocoaTouchFramework 717 | 718 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 719 | 720 | 721 | YES 722 | 3 723 | 1498 724 | 725 | 726 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/OHHTTPStubsDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.alisoftware.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSMainNibFile 26 | MainViewController 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/OHHTTPStubsDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'OHHTTPStubsDemo' target in the 'OHHTTPStubsDemo' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iOS SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/OHHTTPStubsDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 098FBDD415D704E800623941 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 098FBDD315D704E800623941 /* UIKit.framework */; }; 11 | 098FBDD615D704E800623941 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 098FBDD515D704E800623941 /* Foundation.framework */; }; 12 | 098FBDD815D704E800623941 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 098FBDD715D704E800623941 /* CoreGraphics.framework */; }; 13 | 098FBDE015D704E800623941 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 098FBDDF15D704E800623941 /* main.m */; }; 14 | 098FBDED15D7056200623941 /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 098FBDEB15D7056200623941 /* MainViewController.m */; }; 15 | 098FBDEE15D7056200623941 /* MainViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 098FBDEC15D7056200623941 /* MainViewController.xib */; }; 16 | 098FBDF815D70E2600623941 /* stub.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 098FBDF615D70E2600623941 /* stub.jpg */; }; 17 | 098FBDF915D70E2600623941 /* stub.txt in Resources */ = {isa = PBXBuildFile; fileRef = 098FBDF715D70E2600623941 /* stub.txt */; }; 18 | 099C7343169016D800239880 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 099C7342169016D800239880 /* Default-568h@2x.png */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 097935A1161B654E006DB5D5 /* libOHHTTPStubs.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = libOHHTTPStubs.a; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 098FBDCF15D704E800623941 /* OHHTTPStubsDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OHHTTPStubsDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 24 | 098FBDD315D704E800623941 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 25 | 098FBDD515D704E800623941 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 26 | 098FBDD715D704E800623941 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 27 | 098FBDDB15D704E800623941 /* OHHTTPStubsDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OHHTTPStubsDemo-Info.plist"; sourceTree = ""; }; 28 | 098FBDDF15D704E800623941 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 29 | 098FBDE115D704E800623941 /* OHHTTPStubsDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OHHTTPStubsDemo-Prefix.pch"; sourceTree = ""; }; 30 | 098FBDEA15D7056200623941 /* MainViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; 31 | 098FBDEB15D7056200623941 /* MainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; 32 | 098FBDEC15D7056200623941 /* MainViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MainViewController.xib; sourceTree = ""; }; 33 | 098FBDF615D70E2600623941 /* stub.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = stub.jpg; sourceTree = ""; }; 34 | 098FBDF715D70E2600623941 /* stub.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = stub.txt; sourceTree = ""; }; 35 | 099C7342169016D800239880 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 36 | /* End PBXFileReference section */ 37 | 38 | /* Begin PBXFrameworksBuildPhase section */ 39 | 098FBDCC15D704E800623941 /* Frameworks */ = { 40 | isa = PBXFrameworksBuildPhase; 41 | buildActionMask = 2147483647; 42 | files = ( 43 | 098FBDD415D704E800623941 /* UIKit.framework in Frameworks */, 44 | 098FBDD615D704E800623941 /* Foundation.framework in Frameworks */, 45 | 098FBDD815D704E800623941 /* CoreGraphics.framework in Frameworks */, 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | 098FBDC415D704E800623941 = { 53 | isa = PBXGroup; 54 | children = ( 55 | 099C7342169016D800239880 /* Default-568h@2x.png */, 56 | 098FBDD915D704E800623941 /* OHHTTPStubsDemo */, 57 | 098FBDD215D704E800623941 /* Frameworks */, 58 | 098FBDD015D704E800623941 /* Products */, 59 | ); 60 | sourceTree = ""; 61 | }; 62 | 098FBDD015D704E800623941 /* Products */ = { 63 | isa = PBXGroup; 64 | children = ( 65 | 098FBDCF15D704E800623941 /* OHHTTPStubsDemo.app */, 66 | ); 67 | name = Products; 68 | sourceTree = ""; 69 | }; 70 | 098FBDD215D704E800623941 /* Frameworks */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 098FBDD315D704E800623941 /* UIKit.framework */, 74 | 098FBDD515D704E800623941 /* Foundation.framework */, 75 | 098FBDD715D704E800623941 /* CoreGraphics.framework */, 76 | ); 77 | name = Frameworks; 78 | sourceTree = ""; 79 | }; 80 | 098FBDD915D704E800623941 /* OHHTTPStubsDemo */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 098FBDEA15D7056200623941 /* MainViewController.h */, 84 | 098FBDEB15D7056200623941 /* MainViewController.m */, 85 | 098FBDEC15D7056200623941 /* MainViewController.xib */, 86 | 098FBDFA15D70E2F00623941 /* Stubs */, 87 | 098FBDDA15D704E800623941 /* Supporting Files */, 88 | ); 89 | name = OHHTTPStubsDemo; 90 | sourceTree = ""; 91 | }; 92 | 098FBDDA15D704E800623941 /* Supporting Files */ = { 93 | isa = PBXGroup; 94 | children = ( 95 | 098FBDDB15D704E800623941 /* OHHTTPStubsDemo-Info.plist */, 96 | 098FBDDF15D704E800623941 /* main.m */, 97 | 098FBDE115D704E800623941 /* OHHTTPStubsDemo-Prefix.pch */, 98 | ); 99 | name = "Supporting Files"; 100 | sourceTree = ""; 101 | }; 102 | 098FBDFA15D70E2F00623941 /* Stubs */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 097935A1161B654E006DB5D5 /* libOHHTTPStubs.a */, 106 | 098FBDF615D70E2600623941 /* stub.jpg */, 107 | 098FBDF715D70E2600623941 /* stub.txt */, 108 | ); 109 | name = Stubs; 110 | sourceTree = ""; 111 | }; 112 | /* End PBXGroup section */ 113 | 114 | /* Begin PBXNativeTarget section */ 115 | 098FBDCE15D704E800623941 /* OHHTTPStubsDemo */ = { 116 | isa = PBXNativeTarget; 117 | buildConfigurationList = 098FBDE715D704E800623941 /* Build configuration list for PBXNativeTarget "OHHTTPStubsDemo" */; 118 | buildPhases = ( 119 | 098FBDCB15D704E800623941 /* Sources */, 120 | 098FBDCC15D704E800623941 /* Frameworks */, 121 | 098FBDCD15D704E800623941 /* Resources */, 122 | ); 123 | buildRules = ( 124 | ); 125 | dependencies = ( 126 | ); 127 | name = OHHTTPStubsDemo; 128 | productName = OHHTTPStubsDemo; 129 | productReference = 098FBDCF15D704E800623941 /* OHHTTPStubsDemo.app */; 130 | productType = "com.apple.product-type.application"; 131 | }; 132 | /* End PBXNativeTarget section */ 133 | 134 | /* Begin PBXProject section */ 135 | 098FBDC615D704E800623941 /* Project object */ = { 136 | isa = PBXProject; 137 | attributes = { 138 | LastUpgradeCheck = 0510; 139 | ORGANIZATIONNAME = AliSoftware; 140 | }; 141 | buildConfigurationList = 098FBDC915D704E800623941 /* Build configuration list for PBXProject "OHHTTPStubsDemo" */; 142 | compatibilityVersion = "Xcode 3.2"; 143 | developmentRegion = English; 144 | hasScannedForEncodings = 0; 145 | knownRegions = ( 146 | en, 147 | ); 148 | mainGroup = 098FBDC415D704E800623941; 149 | productRefGroup = 098FBDD015D704E800623941 /* Products */; 150 | projectDirPath = ""; 151 | projectRoot = ""; 152 | targets = ( 153 | 098FBDCE15D704E800623941 /* OHHTTPStubsDemo */, 154 | ); 155 | }; 156 | /* End PBXProject section */ 157 | 158 | /* Begin PBXResourcesBuildPhase section */ 159 | 098FBDCD15D704E800623941 /* Resources */ = { 160 | isa = PBXResourcesBuildPhase; 161 | buildActionMask = 2147483647; 162 | files = ( 163 | 098FBDEE15D7056200623941 /* MainViewController.xib in Resources */, 164 | 098FBDF815D70E2600623941 /* stub.jpg in Resources */, 165 | 098FBDF915D70E2600623941 /* stub.txt in Resources */, 166 | 099C7343169016D800239880 /* Default-568h@2x.png in Resources */, 167 | ); 168 | runOnlyForDeploymentPostprocessing = 0; 169 | }; 170 | /* End PBXResourcesBuildPhase section */ 171 | 172 | /* Begin PBXSourcesBuildPhase section */ 173 | 098FBDCB15D704E800623941 /* Sources */ = { 174 | isa = PBXSourcesBuildPhase; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | 098FBDE015D704E800623941 /* main.m in Sources */, 178 | 098FBDED15D7056200623941 /* MainViewController.m in Sources */, 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXSourcesBuildPhase section */ 183 | 184 | /* Begin XCBuildConfiguration section */ 185 | 098FBDE515D704E800623941 /* Debug */ = { 186 | isa = XCBuildConfiguration; 187 | buildSettings = { 188 | ALWAYS_SEARCH_USER_PATHS = NO; 189 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 190 | CLANG_WARN_BOOL_CONVERSION = YES; 191 | CLANG_WARN_CONSTANT_CONVERSION = YES; 192 | CLANG_WARN_EMPTY_BODY = YES; 193 | CLANG_WARN_ENUM_CONVERSION = YES; 194 | CLANG_WARN_INT_CONVERSION = YES; 195 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 196 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 197 | COPY_PHASE_STRIP = NO; 198 | GCC_C_LANGUAGE_STANDARD = gnu99; 199 | GCC_DYNAMIC_NO_PIC = NO; 200 | GCC_OPTIMIZATION_LEVEL = 0; 201 | GCC_PREPROCESSOR_DEFINITIONS = ( 202 | "DEBUG=1", 203 | "$(inherited)", 204 | ); 205 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 206 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 207 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 208 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 209 | GCC_WARN_UNDECLARED_SELECTOR = YES; 210 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 211 | GCC_WARN_UNUSED_FUNCTION = YES; 212 | GCC_WARN_UNUSED_VARIABLE = YES; 213 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 214 | ONLY_ACTIVE_ARCH = YES; 215 | OTHER_LDFLAGS = "-ObjC"; 216 | SDKROOT = iphoneos; 217 | }; 218 | name = Debug; 219 | }; 220 | 098FBDE615D704E800623941 /* Release */ = { 221 | isa = XCBuildConfiguration; 222 | buildSettings = { 223 | ALWAYS_SEARCH_USER_PATHS = NO; 224 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 225 | CLANG_WARN_BOOL_CONVERSION = YES; 226 | CLANG_WARN_CONSTANT_CONVERSION = YES; 227 | CLANG_WARN_EMPTY_BODY = YES; 228 | CLANG_WARN_ENUM_CONVERSION = YES; 229 | CLANG_WARN_INT_CONVERSION = YES; 230 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 231 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 232 | COPY_PHASE_STRIP = YES; 233 | GCC_C_LANGUAGE_STANDARD = gnu99; 234 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 235 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 236 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 237 | GCC_WARN_UNDECLARED_SELECTOR = YES; 238 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 239 | GCC_WARN_UNUSED_FUNCTION = YES; 240 | GCC_WARN_UNUSED_VARIABLE = YES; 241 | IPHONEOS_DEPLOYMENT_TARGET = 5.0; 242 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 243 | OTHER_LDFLAGS = "-ObjC"; 244 | SDKROOT = iphoneos; 245 | VALIDATE_PRODUCT = YES; 246 | }; 247 | name = Release; 248 | }; 249 | 098FBDE815D704E800623941 /* Debug */ = { 250 | isa = XCBuildConfiguration; 251 | buildSettings = { 252 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 253 | GCC_PREFIX_HEADER = "OHHTTPStubsDemo-Prefix.pch"; 254 | INFOPLIST_FILE = "OHHTTPStubsDemo-Info.plist"; 255 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 256 | PRODUCT_NAME = "$(TARGET_NAME)"; 257 | WRAPPER_EXTENSION = app; 258 | }; 259 | name = Debug; 260 | }; 261 | 098FBDE915D704E800623941 /* Release */ = { 262 | isa = XCBuildConfiguration; 263 | buildSettings = { 264 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 265 | GCC_PREFIX_HEADER = "OHHTTPStubsDemo-Prefix.pch"; 266 | INFOPLIST_FILE = "OHHTTPStubsDemo-Info.plist"; 267 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 268 | PRODUCT_NAME = "$(TARGET_NAME)"; 269 | WRAPPER_EXTENSION = app; 270 | }; 271 | name = Release; 272 | }; 273 | /* End XCBuildConfiguration section */ 274 | 275 | /* Begin XCConfigurationList section */ 276 | 098FBDC915D704E800623941 /* Build configuration list for PBXProject "OHHTTPStubsDemo" */ = { 277 | isa = XCConfigurationList; 278 | buildConfigurations = ( 279 | 098FBDE515D704E800623941 /* Debug */, 280 | 098FBDE615D704E800623941 /* Release */, 281 | ); 282 | defaultConfigurationIsVisible = 0; 283 | defaultConfigurationName = Release; 284 | }; 285 | 098FBDE715D704E800623941 /* Build configuration list for PBXNativeTarget "OHHTTPStubsDemo" */ = { 286 | isa = XCConfigurationList; 287 | buildConfigurations = ( 288 | 098FBDE815D704E800623941 /* Debug */, 289 | 098FBDE915D704E800623941 /* Release */, 290 | ); 291 | defaultConfigurationIsVisible = 0; 292 | defaultConfigurationName = Release; 293 | }; 294 | /* End XCConfigurationList section */ 295 | }; 296 | rootObject = 098FBDC615D704E800623941 /* Project object */; 297 | } 298 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/OHHTTPStubsDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/OHHTTPStubsDemo.xcodeproj/xcshareddata/xcschemes/OHHTTPStubsDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 44 | 45 | 46 | 47 | 48 | 54 | 55 | 56 | 57 | 66 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // OHHTTPStubsDemo 4 | // 5 | // Created by Olivier Halligon on 11/08/12. 6 | // Copyright (c) 2012 AliSoftware. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | int main(int argc, char *argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, nil); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /OHHTTPStubsDemo/stub.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/github/OHHTTPStubs/8761af63dc87ef8dd3944f2248ac4e1f6256c4c8/OHHTTPStubsDemo/stub.jpg -------------------------------------------------------------------------------- /OHHTTPStubsDemo/stub.txt: -------------------------------------------------------------------------------- 1 | This is the text from your stub. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OHHTTPStubs 2 | =========== 3 | 4 | A class to stub network requests easily: test your apps with fake network data (stubbed from file) and custom response time 5 | 6 | * [Basic Usage](#basic-usage) 7 | * [The `OHHTTPStubsResponse` object](#the-ohhttpstubsresponse-object) 8 | * [Advanced Usage](#advanced-usage) 9 | * [Return a response depending on the request](#return-a-response-depending-on-the-request) 10 | * [Using download speed instead of responseTime](#using-download-speed-instead-of-responsetime) 11 | * [Return quickly when `onlyCheck=YES`](#return-quickly-when-onlycheckyes) 12 | * [Stack multiple requestHandlers](#stack-multiple-requesthandlers) 13 | * [Complete Examples](#complete-examples) 14 | * [Installing in your projects](#installing-in-your-projects) 15 | * [Detailed integration instructions](#detailed-integration-instructions) 16 | * [Xcode4 Dependencies bug](#xcode4-dependencies-bug) 17 | * [Private API Warning](#private-api-warning) 18 | * [CocoaPods](#cocoapods) 19 | * [About OHHTTPStubs Unit Tests](#about-ohhttpstubs-unit-tests) 20 | * [Change Log](#change-log) 21 | * [License and Credits](#license-and-credits) 22 | 23 | ---- 24 | 25 | ## Basic Usage 26 | 27 | This is aimed to be very simple to use. It uses block to intercept outgoing requests and allow you to 28 | return data from a file instead. 29 | 30 | ##### This is the most simple way to use it: 31 | 32 | [OHHTTPStubs addRequestHandler:^OHHTTPStubsResponse*(NSURLRequest *request, BOOL onlyCheck) { 33 | return [OHHTTPStubsResponse responseWithFile:@"response.json" contentType:@"text/json" responseTime:2.0]; 34 | }]; 35 | 36 | This will return the `NSData` corresponding to the content of the `"response.json"` file (that must be in your bundle) 37 | with a `"Content-Type"` header of `"text/json"` in the HTTP response, after 2 seconds. 38 | 39 | ##### We can also conditionally stub only certain requests, like this: 40 | 41 | [OHHTTPStubs shouldStubRequestsPassingTest:^BOOL(NSURLRequest *request) { 42 | // Only stub requests to "*.json" files 43 | return [request.URL.absoluteString.lastPathComponent.pathExtension isEqualToString:@"json"]; 44 | } withStubResponse:^OHHTTPStubsResponse*(NSURLRequest *request) { 45 | // Stub it with our "response.json" stub file 46 | return [OHHTTPStubsResponse responseWithFile:@"response.json" contentType:@"text/json" responseTime:2.0]; 47 | }]; 48 | 49 | ##### Then each time a network request is done by your application 50 | 51 | For every request sent, whatever the framework used (`NSURLConnection`, 52 | [`AFNetworking`](https://github.com/AFNetworking/AFNetworking/), or anything else): 53 | 54 | * If you used `shouldStubRequestsPassingTest:withStubResponse:` 55 | * The block passed as first argument will be called to check if we need to stub this request. 56 | * If this block returned YES, the block passed as second argument will be called to let you return an `OHHTTPStubsResponse` object, describing the fake response to return. 57 | * If you used `addRequestHandler:` 58 | * If you return a non-nil `OHHTTPStubsResponse`, the request will be stubbed by returning the corresponding fake response. 59 | * If your return `nil`, the normal request will be sent (no stubbing). 60 | 61 | _(See also "[Return quickly when `onlyCheck=YES`](#return-quickly-when-onlycheckyes)" below)_ 62 | 63 | 64 | ## The `OHHTTPStubsResponse` object 65 | 66 | The `OHHTTPStubsResponse` class, describing the fake response to return, exposes multiple initializers: 67 | 68 | ##### The designed intializer 69 | +(id)responseWithData:(NSData*)data 70 | statusCode:(int)statusCode 71 | responseTime:(NSTimeInterval)responseTime 72 | headers:(NSDictionary*)httpHeaders; 73 | 74 | ##### Commodity initializer to load data from a file in your bundle 75 | +(id)responseWithFile:(NSString*)fileName 76 | statusCode:(int)statusCode 77 | responseTime:(NSTimeInterval)responseTime 78 | headers:(NSDictionary*)httpHeaders; 79 | 80 | ##### Useful short-form initializer to load data from a file in your bundle, using the specified "Content-Type" header 81 | +(id)responseWithFile:(NSString*)fileName 82 | contentType:(NSString*)contentType 83 | responseTime:(NSTimeInterval)responseTime; 84 | 85 | ##### To respond with an error instead of a success 86 | +(id)responseWithError:(NSError*)error; 87 | _(e.g. you could use an error like `[NSError errorWithDomain:NSURLErrorDomain code:404 userInfo:nil]`)_ 88 | 89 | 90 | ## Advanced Usage 91 | 92 | ### Return a response depending on the request 93 | 94 | Of course, and that's the main reason this is implemented with blocks, 95 | you can do whatever you need in the block implementation. This includes 96 | checking the request URL to see if you want to return a stub or not, 97 | and pick the right file according to the requested URL. 98 | 99 | You can use either `addRequestHandler:` or `shouldStubRequestsPassingTest:withStubResponse:` to install a stubbed request. 100 | [See below](#return-quickly-when-onlycheckyes). 101 | 102 | Example: 103 | 104 | [OHHTTPStubs addRequestHandler:^OHHTTPStubsResponse*(NSURLRequest *request, BOOL onlyCheck) 105 | { 106 | NSString* basename = request.URL.absoluteString.lastPathComponent; 107 | if ([basename.pathExtension isEqualToString:@"json"]) { 108 | return [OHHTTPStubsResponse responseWithFile:basename contentType:@"text/json" responseTime:2.0]; 109 | } else { 110 | return nil; // Don't stub 111 | } 112 | }]; 113 | 114 | 115 | ### Using download speed instead of responseTime 116 | 117 | When building the `OHHTTPStubsResponse` object, you can specify a response time (in seconds) so 118 | that the sending of the fake response will be postponed. This allows you to simulate a slow network for example. 119 | 120 | If you specify a negative value for the responseTime parameter, instead of being interpreted as 121 | a time in seconds, it will be interpreted as a download speed in KBytes/s. 122 | In that case, the response time will be computed using the size of the response's data to simulate 123 | the indicated download speed. 124 | 125 | The `OHHTTPStubsResponse` header defines some constants for standard download speeds: 126 | * `OHHTTPStubsDownloadSpeedGPRS` : 56 kbps (7 KB/s) 127 | * `OHHTTPStubsDownloadSpeedEDGE` : 128 kbps (16 KB/s) 128 | * `OHHTTPStubsDownloadSpeed3G` : 3200 kbps (400 KB/s) 129 | * `OHHTTPStubsDownloadSpeed3GPlus` : 7200 kbps (900 KB/s) 130 | * `OHHTTPStubsDownloadSpeedWifi` : 12000 kbps (1500 KB/s) 131 | 132 | ### Return quickly when `onlyCheck=YES` 133 | 134 | When using `addRequestHandler:`, if the `onlyCheck` parameter of the requestHandler block is `YES`, then it means that the handler is called 135 | only to check if you will be able to return a stubbed response or if it has to do the standard request. 136 | In this scenario, the response will not actually be used but will only be compared to `nil` to check if it has to be stubbed later. 137 | _The handler will be called later again (with `onlyCheck=NO`) to fetch the actual `OHHTTPStubsResponse` object._ 138 | 139 | So in such cases (`onlyCheck==YES`), you can simply return `nil` if you don't want to provide a stubbed response, 140 | and **_any_ non-nil value** to indicate that you will provide a stubbed response later. 141 | 142 | This may be useful if you intend to do some not-so-fast work to build your real `OHHTTPStubsResponse` 143 | (like reading some large file for example): in that case you can quickly return a dummy value when `onlyCheck==YES` 144 | without the burden of building the actual `OHHTTPStubsResponse` object. 145 | You will obviously return the real `OHHTTPStubsResponse` in the later call when `onlyCheck==NO`. 146 | 147 | _There is a macro `OHHTTPStubsResponseUseStub` provided in the header that you can use as a dummy return value for that purpose._ 148 | 149 | --- 150 | 151 | To avoid forgetting about quickly return if the handler is called only for checking the availability of a stub, you may 152 | prefer using the `shouldStubRequestsPassingTest:withStubResponse:` class method, which uses two distinct blocks: one to 153 | only quickly check that the request should be stubbed, and the other to build and return the actual stubbed response. 154 | 155 | Example: 156 | 157 | [OHHTTPStubs shouldStubRequestPassingTest:^BOOL(NSURLRequest *request) { 158 | NSString* basename = request.URL.absoluteString.lastPathComponent; 159 | return [basename.pathExtension isEqualToString:@"json"]; // only stub requests for "*.json" files 160 | } withStubResponse:^OHHTTPStubsResponse* (NSURLRequest* request))handler { 161 | // This block will only be called if the previous one has returned YES (so only for "*.json" files) 162 | NSString* basename = request.URL.absoluteString.lastPathComponent; 163 | return [OHHTTPStubsResponse responseWithFile:basename contentType:@"text/json" responseTime:2.0]; 164 | }]; 165 | 166 | > Note: in practice, this method calls `addResponseHandler:`, and pass it a new block that: 167 | > * calls the first block to check if we need to stub, and 168 | > * directly return `OHHTTPStubsResponseUseStub` or `OHHTTPStubsResponseDontUseStub` if `onlyCheck=YES` 169 | > * or call the second block to return the actual stub only if `onlyCheck=NO`. 170 | 171 | _Note that even if you want to stub all your requests unconditionally, it is still better to 172 | use `shouldStubRequestsPassingTest:withStubResponse:` with the first block always returning `YES`, 173 | because it will prevent building the whole stubbed response multiple times (once or more when only checking, 174 | and one final time when actually returning it)._ 175 | 176 | 177 | ### Stack multiple requestHandlers 178 | 179 | You can call `addRequestHandler:` or `shouldStubRequestsPassingTest:withStubResponse:` multiple times. 180 | It will just add the response handlers in an internal list of handlers. 181 | 182 | When a network request is performed by the system, the response handlers are called in the reverse 183 | order that they have been added, the last added handler having priority over the first added ones. 184 | The first handler that returns a stub (non-nil response for `addRequestHandler:`, 185 | or first block returning YES for `shouldStubRequestsPassingTest:withStubResponse:`) is then used to reply to the request. 186 | 187 | _This may be useful to install different stubs in different classes (say different UIViewControllers) 188 | and various places in your application, or to separate different stubs and stubbing conditions 189 | (like some stubs for images and other stubs for JSON files) more easily. 190 | See the `OHHTTPStubsDemo` project for a typical example._ 191 | 192 | You can remove the latest added handler with the `removeLastRequestHandler` method. 193 | 194 | You can also remove any given handler with the `removeRequestHandler:` method. 195 | This method takes as a parameter the object returned by `addRequestHandler:` or `shouldStubRequestsPassingTest:withStubResponse:`. 196 | _Note that this returned object is already retained by `OHHTTPStubs` while the stub is installed, 197 | so you may keep it in a `__weak` variable (no need to keep a `__strong` reference)._ 198 | 199 | 200 | 201 | ## Complete examples 202 | 203 | Here is another example code below that uses the various techniques explained above. 204 | For a complete Xcode projet, see the `OHHTTPStubsDemo.xcworkspace` project in the repository. 205 | 206 | 207 | NSArray* stubs = [NSArray arrayWithObjects:@"file1", @"file2", nil]; 208 | 209 | [OHHTTPStubs shouldStubRequestPassingTest:^OHHTTPStubsResponse*(NSURLRequest *request) { 210 | return [stubs containsObject:request.URL.absoluteString.lastPathComponent]; 211 | } withStubResponse:^OHHTTPStubsResponse* (NSURLRequest* request))handler { 212 | NSString* file = [request.URL.absoluteString.lastPathComponent 213 | stringByAppendingPathExtension:@"json"]; 214 | return [OHHTTPStubsResponse responseWithFile:file contentType:@"text/json" 215 | responseTime:OHHTTPStubsDownloadSpeedEDGE]; 216 | }]; 217 | 218 | ... 219 | 220 | // Then this call (sending a request using the AFNetworking framework) will actually 221 | // receive a fake response issued from the file "file1.json" 222 | NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.example.com/file1"]]; 223 | [[AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) 224 | { 225 | ... 226 | } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) 227 | { 228 | ... 229 | }] start]; 230 | 231 | 232 | 233 | ## Installing in your projects 234 | 235 | The `OHHTTPStubs` project is provided as a Xcode project that generates a static library, to easily integrate it with your project. 236 | 237 | You simply need to add its xcodeproj to your workspace and link your app against the `libOHHTTPStubs.a` library. 238 | 239 | ### Detailed integration instructions 240 | 241 | 1. Add the `OHHTTPStubs.xcodeproj` project to your application workspace, next to your application project 242 | 2. Build the library once for the "iOS Device" destination _(if you skipt this, you will likely have the Xcode4 bug described below)_ 243 | 3. Link `libOHHTTPStubs.a` with your application project. To do this: 244 | * Select your application project in the Project Navigator, then select your target in which you want to use `OHHTTPStubs` 245 | (for example **your Tests target** if you will only use `OHHTTPStubs` in your Unit Tests) 246 | * Go to the "Build Phase" tab and open the "Link Binary With Libraries" phase 247 | * Use the "+" button to add the `libOHHTTPStubs.a` library to the libraries linked with your project 248 | 4. Select the `libOHHTTPStubs.a` file reference that has been added to your application projet, and change the "Location" dropdown 249 | (in the "File Inspector" pane) to "Relative to Build Products" if it is not already. 250 | 6. When you need to use `OHHTTPStubs` classes, import the headers using `#import ` 251 | 252 | ### Xcode4 Dependencies bug 253 | 254 | Steps 2 and 4 are needed due to a bug in Xcode4 that would otherwise not reference the library with the correct path and as a built product. 255 | 256 | If the `libOHHTTPStubs.a` file is not referenced as "Relative to Build Products", Xcode4 won't be able to detect implicit dependencies and won't 257 | build the library before building your application, resulting in a linker error. 258 | 259 | If you encounter this issue, please read the [detailed instructions here](http://github.com/AliSoftware/OHHTTPStubs/wiki/Detailed-Integration-Instruction)._ 260 | 261 | ### Private API Warning 262 | 263 | `OHHTTPStubs` is designed to be used **in test/debug code only**. 264 | **Don't link with it in production code when you compile your final application for the AppStore**. 265 | 266 | > _Its code use a private API to build an `NSHTTPURLResponse`, which is not authorized by Apple in applications published on the AppStore. 267 | So you will probably only link it with your Unit Tests target, or inside some `#if DEBUG`/`#endif` portions of your code._ 268 | 269 | ### CocoaPods 270 | 271 | `OHHTTPStubs` is referenced in [`CocoaPods`](https://github.com/CocoaPods/Specs/tree/master/OHHTTPStubs), so if you use [CocoaPods](http://cocoapods.org/) you can add `pod OHHTTPStubs` to your Podfile instead of following the above instructions. 272 | 273 | Be careful anyway to include it only in your test targets, or only use its symbols in `#if DEBUG` portions, 274 | so that its code (and the private API it uses) is not included in your release for the AppStore, as explained above. 275 | 276 | 277 | ## About `OHHTTPStubs` Unit Tests 278 | 279 | `OHHTTPStubs` include some *Unit Tests*, and some of them test cases when using `OHHTTPStubs` with the [`AFNetworking`](https://github.com/AFNetworking/AFNetworking/) framework. 280 | To implement those test cases, `AFNetworking` has been added as a _GIT submodule_ inside the "Unit Tests" folder. 281 | This means that if you want to be able to run `OHHTTPStubs`' Unit Tests, 282 | you need to include submodules when cloning, by using the `--recursive` option: 283 | `git clone --recursive `. 284 | Alternatively if you didn't include the `--recursive` flag when cloning, you can use `git submodule init` and then `git submodule update` 285 | on your already cloned working copy to initialize and fetch/update the submodules. 286 | 287 | _This is only needed if you intend to run the `OHHTTPStubs` Unit Tests, to check the correct behavior of `OHHTTPStubs` 288 | in conjunction with `AFNetworking`. If you only intend to directly use the `OHHTTPStubs`'s 289 | produced library and will never run the `OHHTTPStubs` Unit Tests, the `AFNetworking` submodule is not needed at all._ 290 | 291 | ## Change Log 292 | 293 | The changelog is available [here in the dedicated wiki page](https://github.com/AliSoftware/OHHTTPStubs/wiki/ChangeLog). 294 | 295 | 296 | ## License and Credits 297 | 298 | This project is brought to you by Olivier Halligon and is under MIT License 299 | 300 | It has been inspired by [this article from InfiniteLoop.dk](http://www.infinite-loop.dk/blog/2011/09/using-nsurlprotocol-for-injecting-test-data/) 301 | _(See also his [GitHub repository](https://github.com/InfiniteLoopDK/ILTesting))_ 302 | 303 | --------------------------------------------------------------------------------