diff options
Diffstat (limited to 'platform/ios/uitest/OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.m')
m--------- | platform/ios/uitest/OHHTTPStubs | 0 | ||||
-rw-r--r-- | platform/ios/uitest/OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.m | 530 |
2 files changed, 0 insertions, 530 deletions
diff --git a/platform/ios/uitest/OHHTTPStubs b/platform/ios/uitest/OHHTTPStubs new file mode 160000 +Subproject deed01a1592210a4c37f3f5c5f2b32fe0e41c60 diff --git a/platform/ios/uitest/OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.m b/platform/ios/uitest/OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.m deleted file mode 100644 index 4fa31f907b..0000000000 --- a/platform/ios/uitest/OHHTTPStubs/OHHTTPStubs/Sources/OHHTTPStubs.m +++ /dev/null @@ -1,530 +0,0 @@ -/*********************************************************************************** - * - * Copyright (c) 2012 Olivier Halligon - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - * - ***********************************************************************************/ - -#if ! __has_feature(objc_arc) -#error This file is expected to be compiled with ARC turned ON -#endif - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Imports - -#import "OHHTTPStubs.h" - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Types & Constants - -@interface OHHTTPStubsProtocol : NSURLProtocol @end - -static NSTimeInterval const kSlotTime = 0.25; // Must be >0. We will send a chunk of the data from the stream each 'slotTime' seconds - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Private Interfaces - -@interface OHHTTPStubs() -+ (instancetype)sharedInstance; -@property(atomic, copy) NSMutableArray* stubDescriptors; -@property(atomic, copy) void (^onStubActivationBlock)(NSURLRequest*, id<OHHTTPStubsDescriptor>); -@end - -@interface OHHTTPStubsDescriptor : NSObject <OHHTTPStubsDescriptor> -@property(atomic, copy) OHHTTPStubsTestBlock testBlock; -@property(atomic, copy) OHHTTPStubsResponseBlock responseBlock; -@end - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - OHHTTPStubsDescriptor Implementation - -@implementation OHHTTPStubsDescriptor - -@synthesize name = _name; - -+(instancetype)stubDescriptorWithTestBlock:(OHHTTPStubsTestBlock)testBlock - responseBlock:(OHHTTPStubsResponseBlock)responseBlock -{ - OHHTTPStubsDescriptor* stub = [OHHTTPStubsDescriptor new]; - stub.testBlock = testBlock; - stub.responseBlock = responseBlock; - return stub; -} - --(NSString*)description -{ - return [NSString stringWithFormat:@"<%@ %p : %@>", self.class, self, self.name]; -} - -@end - - - - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - OHHTTPStubs Implementation - -@implementation OHHTTPStubs - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Singleton methods - -+ (instancetype)sharedInstance -{ - static OHHTTPStubs *sharedInstance = nil; - - static dispatch_once_t predicate; - dispatch_once(&predicate, ^{ - sharedInstance = [[self alloc] init]; - }); - - return sharedInstance; -} - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Setup & Teardown - -+ (void)initialize -{ - if (self == [OHHTTPStubs class]) - { - [self setEnabled:YES]; - } -} -- (instancetype)init -{ - self = [super init]; - if (self) - { - _stubDescriptors = [NSMutableArray array]; - } - return self; -} - -- (void)dealloc -{ - [self.class setEnabled:NO]; -} - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Public class methods - -#pragma mark > Adding & Removing stubs - -+(id<OHHTTPStubsDescriptor>)stubRequestsPassingTest:(OHHTTPStubsTestBlock)testBlock - withStubResponse:(OHHTTPStubsResponseBlock)responseBlock -{ - OHHTTPStubsDescriptor* stub = [OHHTTPStubsDescriptor stubDescriptorWithTestBlock:testBlock - responseBlock:responseBlock]; - [OHHTTPStubs.sharedInstance addStub:stub]; - return stub; -} - -+(BOOL)removeStub:(id<OHHTTPStubsDescriptor>)stubDesc -{ - return [OHHTTPStubs.sharedInstance removeStub:stubDesc]; -} - -+(void)removeAllStubs -{ - [OHHTTPStubs.sharedInstance removeAllStubs]; -} - -#pragma mark > Disabling & Re-Enabling stubs - -+(void)setEnabled:(BOOL)enable -{ - static BOOL currentEnabledState = NO; - if (enable && !currentEnabledState) - { - [NSURLProtocol registerClass:OHHTTPStubsProtocol.class]; - } - else if (!enable && currentEnabledState) - { - [NSURLProtocol unregisterClass:OHHTTPStubsProtocol.class]; - } - currentEnabledState = enable; -} - -#if defined(__IPHONE_7_0) || defined(__MAC_10_9) -+ (void)setEnabled:(BOOL)enable forSessionConfiguration:(NSURLSessionConfiguration*)sessionConfig -{ - // Runtime check to make sure the API is available on this version - if ( [sessionConfig respondsToSelector:@selector(protocolClasses)] - && [sessionConfig respondsToSelector:@selector(setProtocolClasses:)]) - { - NSMutableArray * urlProtocolClasses = [NSMutableArray arrayWithArray:sessionConfig.protocolClasses]; - Class protoCls = OHHTTPStubsProtocol.class; - if (enable && ![urlProtocolClasses containsObject:protoCls]) - { - [urlProtocolClasses insertObject:protoCls atIndex:0]; - } - else if (!enable && [urlProtocolClasses containsObject:protoCls]) - { - [urlProtocolClasses removeObject:protoCls]; - } - sessionConfig.protocolClasses = urlProtocolClasses; - } - else - { - NSLog(@"[OHHTTPStubs] %@ is only available when running on iOS7+/OSX9+. " - @"Use conditions like 'if ([NSURLSessionConfiguration class])' to only call " - @"this method if the user is running iOS7+/OSX9+.", NSStringFromSelector(_cmd)); - } -} -#endif - -#pragma mark > Debug Methods - -+(NSArray*)allStubs -{ - return [OHHTTPStubs.sharedInstance stubDescriptors]; -} - -+(void)onStubActivation:( void(^)(NSURLRequest* request, id<OHHTTPStubsDescriptor> stub) )block -{ - [OHHTTPStubs.sharedInstance setOnStubActivationBlock:block]; -} - - - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Private instance methods - --(void)addStub:(OHHTTPStubsDescriptor*)stubDesc -{ - @synchronized(_stubDescriptors) - { - [_stubDescriptors addObject:stubDesc]; - } -} - --(BOOL)removeStub:(id<OHHTTPStubsDescriptor>)stubDesc -{ - BOOL handlerFound = NO; - @synchronized(_stubDescriptors) - { - handlerFound = [_stubDescriptors containsObject:stubDesc]; - [_stubDescriptors removeObject:stubDesc]; - } - return handlerFound; -} - --(void)removeAllStubs -{ - @synchronized(_stubDescriptors) - { - [_stubDescriptors removeAllObjects]; - } -} - -- (OHHTTPStubsDescriptor*)firstStubPassingTestForRequest:(NSURLRequest*)request -{ - OHHTTPStubsDescriptor* foundStub = nil; - @synchronized(_stubDescriptors) - { - for(OHHTTPStubsDescriptor* stub in _stubDescriptors.reverseObjectEnumerator) - { - if (stub.testBlock(request)) - { - foundStub = stub; - break; - } - } - } - return foundStub; -} - -@end - - - - - - - - - - -//////////////////////////////////////////////////////////////////////////////// -#pragma mark - Private Protocol Class - -@interface OHHTTPStubsProtocol() -@property(assign) BOOL stopped; -@property(strong) OHHTTPStubsDescriptor* stub; -@property(assign) CFRunLoopRef clientRunLoop; -- (void)executeOnClientRunLoopAfterDelay:(NSTimeInterval)delayInSeconds block:(dispatch_block_t)block; -@end - -@implementation OHHTTPStubsProtocol - -+ (BOOL)canInitWithRequest:(NSURLRequest *)request -{ - return ([OHHTTPStubs.sharedInstance firstStubPassingTestForRequest:request] != nil); -} - -- (id)initWithRequest:(NSURLRequest *)request cachedResponse:(NSCachedURLResponse *)response client:(id<NSURLProtocolClient>)client -{ - // Make super sure that we never use a cached response. - OHHTTPStubsProtocol* proto = [super initWithRequest:request cachedResponse:nil client:client]; - proto.stub = [OHHTTPStubs.sharedInstance firstStubPassingTestForRequest:request]; - return proto; -} - -+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request -{ - return request; -} - -- (NSCachedURLResponse *)cachedResponse -{ - return nil; -} - -- (void)startLoading -{ - self.clientRunLoop = CFRunLoopGetCurrent(); - NSURLRequest* request = self.request; - id<NSURLProtocolClient> client = self.client; - - if (!self.stub) - { - NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys: - @"It seems like the stub has been removed BEFORE the response had time to be sent.", - NSLocalizedFailureReasonErrorKey, - @"For more info, see https://github.com/AliSoftware/OHHTTPStubs/wiki/OHHTTPStubs-and-asynchronous-tests", - NSLocalizedRecoverySuggestionErrorKey, - request.URL, // Stop right here if request.URL is nil - NSURLErrorFailingURLErrorKey, - nil]; - NSError* error = [NSError errorWithDomain:@"OHHTTPStubs" code:500 userInfo:userInfo]; - [client URLProtocol:self didFailWithError:error]; - return; - } - - OHHTTPStubsResponse* responseStub = self.stub.responseBlock(request); - - if (OHHTTPStubs.sharedInstance.onStubActivationBlock) - { - OHHTTPStubs.sharedInstance.onStubActivationBlock(request, self.stub); - } - - if (responseStub.error == nil) - { - NSHTTPURLResponse* urlResponse = [[NSHTTPURLResponse alloc] initWithURL:request.URL - statusCode:responseStub.statusCode - HTTPVersion:@"HTTP/1.1" - headerFields:responseStub.httpHeaders]; - - // Cookies handling - if (request.HTTPShouldHandleCookies && request.URL) - { - NSArray* cookies = [NSHTTPCookie cookiesWithResponseHeaderFields:responseStub.httpHeaders forURL:request.URL]; - if (cookies) - { - [NSHTTPCookieStorage.sharedHTTPCookieStorage setCookies:cookies forURL:request.URL mainDocumentURL:request.mainDocumentURL]; - } - } - - - NSString* redirectLocation = (responseStub.httpHeaders)[@"Location"]; - NSURL* redirectLocationURL; - if (redirectLocation) - { - redirectLocationURL = [NSURL URLWithString:redirectLocation]; - } - else - { - redirectLocationURL = nil; - } - if (((responseStub.statusCode > 300) && (responseStub.statusCode < 400)) && redirectLocationURL) - { - NSURLRequest* redirectRequest = [NSURLRequest requestWithURL:redirectLocationURL]; - [self executeOnClientRunLoopAfterDelay:responseStub.requestTime block:^{ - if (!self.stopped) - { - [client URLProtocol:self wasRedirectedToRequest:redirectRequest redirectResponse:urlResponse]; - } - }]; - } - else - { - [self executeOnClientRunLoopAfterDelay:responseStub.requestTime block:^{ - if (!self.stopped) - { - [client URLProtocol:self didReceiveResponse:urlResponse cacheStoragePolicy:NSURLCacheStorageNotAllowed]; - if(responseStub.inputStream.streamStatus == NSStreamStatusNotOpen) - { - [responseStub.inputStream open]; - } - [self streamDataForClient:client - withStubResponse:responseStub - completion:^(NSError * error) - { - [responseStub.inputStream close]; - if (error==nil) - { - [client URLProtocolDidFinishLoading:self]; - } - else - { - [client URLProtocol:self didFailWithError:responseStub.error]; - } - }]; - } - }]; - } - } else { - // Send the canned error - [self executeOnClientRunLoopAfterDelay:responseStub.responseTime block:^{ - if (!self.stopped) - { - [client URLProtocol:self didFailWithError:responseStub.error]; - } - }]; - } -} - -- (void)stopLoading -{ - self.stopped = YES; -} - -typedef struct { - NSTimeInterval slotTime; - double chunkSizePerSlot; - double cumulativeChunkSize; -} OHHTTPStubsStreamTimingInfo; - -- (void)streamDataForClient:(id<NSURLProtocolClient>)client - withStubResponse:(OHHTTPStubsResponse*)stubResponse - completion:(void(^)(NSError * error))completion -{ - if ((stubResponse.dataSize>0) && stubResponse.inputStream.hasBytesAvailable && (!self.stopped)) - { - // Compute timing data once and for all for this stub - - OHHTTPStubsStreamTimingInfo timingInfo = { - .slotTime = kSlotTime, // Must be >0. We will send a chunk of data from the stream each 'slotTime' seconds - .cumulativeChunkSize = 0 - }; - - if(stubResponse.responseTime < 0) - { - // Bytes send each 'slotTime' seconds = Speed in KB/s * 1000 * slotTime in seconds - timingInfo.chunkSizePerSlot = (fabs(stubResponse.responseTime) * 1000) * timingInfo.slotTime; - } - else if (stubResponse.responseTime < kSlotTime) // includes case when responseTime == 0 - { - // We want to send the whole data quicker than the slotTime, so send it all in one chunk. - timingInfo.chunkSizePerSlot = stubResponse.dataSize; - timingInfo.slotTime = stubResponse.responseTime; - } - else - { - // Bytes send each 'slotTime' seconds = (Whole size in bytes / response time) * slotTime = speed in bps * slotTime in seconds - timingInfo.chunkSizePerSlot = ((stubResponse.dataSize/stubResponse.responseTime) * timingInfo.slotTime); - } - - [self streamDataForClient:client - fromStream:stubResponse.inputStream - timingInfo:timingInfo - completion:completion]; - } - else - { - if (completion) - { - completion(nil); - } - } -} - -- (void) streamDataForClient:(id<NSURLProtocolClient>)client - fromStream:(NSInputStream*)inputStream - timingInfo:(OHHTTPStubsStreamTimingInfo)timingInfo - completion:(void(^)(NSError * error))completion -{ - NSParameterAssert(timingInfo.chunkSizePerSlot > 0); - - if (inputStream.hasBytesAvailable && (!self.stopped)) - { - // This is needed in case we computed a non-integer chunkSizePerSlot, to avoid cumulative errors - double cumulativeChunkSizeAfterRead = timingInfo.cumulativeChunkSize + timingInfo.chunkSizePerSlot; - NSUInteger chunkSizeToRead = floor(cumulativeChunkSizeAfterRead) - floor(timingInfo.cumulativeChunkSize); - timingInfo.cumulativeChunkSize = cumulativeChunkSizeAfterRead; - - if (chunkSizeToRead == 0) - { - // Nothing to read at this pass, but probably later - [self executeOnClientRunLoopAfterDelay:timingInfo.slotTime block:^{ - [self streamDataForClient:client fromStream:inputStream - timingInfo:timingInfo completion:completion]; - }]; - } else { - uint8_t* buffer = (uint8_t*)malloc(sizeof(uint8_t)*chunkSizeToRead); - NSInteger bytesRead = [inputStream read:buffer maxLength:chunkSizeToRead]; - if (bytesRead > 0) - { - NSData * data = [NSData dataWithBytes:buffer length:bytesRead]; - // Wait for 'slotTime' seconds before sending the chunk. - // If bytesRead < chunkSizePerSlot (because we are near the EOF), adjust slotTime proportionally to the bytes remaining - [self executeOnClientRunLoopAfterDelay:((double)bytesRead / (double)chunkSizeToRead) * timingInfo.slotTime block:^{ - [client URLProtocol:self didLoadData:data]; - [self streamDataForClient:client fromStream:inputStream - timingInfo:timingInfo completion:completion]; - }]; - } - else - { - if (completion) - { - // Note: We may also arrive here with no error if we were just at the end of the stream (EOF) - // In that case, hasBytesAvailable did return YES (because at the limit of OEF) but nothing were read (because EOF) - // But then in that case inputStream.streamError will be nil so that's cool, we won't return an error anyway - completion(inputStream.streamError); - } - } - free(buffer); - } - } - else - { - if (completion) - { - completion(nil); - } - } -} - -///////////////////////////////////////////// -// Delayed execution utility methods -///////////////////////////////////////////// - -- (void)executeOnClientRunLoopAfterDelay:(NSTimeInterval)delayInSeconds block:(dispatch_block_t)block -{ - dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); - dispatch_after(popTime, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - CFRunLoopPerformBlock(self.clientRunLoop, kCFRunLoopDefaultMode, block); - CFRunLoopWakeUp(self.clientRunLoop); - }); -} - -@end |