diff options
Diffstat (limited to 'platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m')
-rw-r--r-- | platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m | 367 |
1 files changed, 367 insertions, 0 deletions
diff --git a/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m b/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m new file mode 100644 index 0000000000..ad71dafd48 --- /dev/null +++ b/platform/ios/Integration Tests/MGLMapViewPendingBlockTests.m @@ -0,0 +1,367 @@ +#import "MGLMapViewIntegrationTest.h" +#import "MGLTestUtility.h" + +@interface MGLMapView (MGLMapViewPendingBlockTests) +@property (nonatomic) NSMutableArray *pendingCompletionBlocks; +- (void)pauseRendering:(__unused NSNotification *)notification; +@end + +@interface MGLMapViewPendingBlockTests : MGLMapViewIntegrationTest +@property (nonatomic, copy) void (^observation)(NSDictionary*); +@property (nonatomic) BOOL completionHandlerCalled; +@end + +@implementation MGLMapViewPendingBlockTests + +- (void)testSetCenterCoordinate { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + [strongSelf.mapView setCenterCoordinate:CLLocationCoordinate2DMake(10.0, 10.0) + zoomLevel:10.0 + direction:0 + animated:NO + completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testSetCenterCoordinateAnimated { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + [strongSelf.mapView setCenterCoordinate:CLLocationCoordinate2DMake(10.0, 10.0) + zoomLevel:10.0 + direction:0 + animated:YES + completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testSetVisibleCoordinateBounds { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + [strongSelf.mapView setVisibleCoordinateBounds:unitBounds + edgePadding:UIEdgeInsetsZero + animated:NO + completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testSetVisibleCoordinateBoundsAnimated { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + [strongSelf.mapView setVisibleCoordinateBounds:unitBounds + edgePadding:UIEdgeInsetsZero + animated:YES + completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testSetCamera { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + MGLMapCamera *camera = [strongSelf.mapView cameraThatFitsCoordinateBounds:unitBounds]; + + [strongSelf.mapView setCamera:camera withDuration:0.0 animationTimingFunction:nil completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testSetCameraAnimated { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + MGLMapCamera *camera = [strongSelf.mapView cameraThatFitsCoordinateBounds:unitBounds]; + + [strongSelf.mapView setCamera:camera withDuration:0.3 animationTimingFunction:nil completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +// Marked as pending due to https://github.com/mapbox/mapbox-gl-native/issues/15471 +- (void)testFlyToCameraPENDING { + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + MGLMapCamera *camera = [strongSelf.mapView cameraThatFitsCoordinateBounds:unitBounds]; + + [strongSelf.mapView flyToCamera:camera withDuration:0.0 completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + +- (void)testFlyToCameraAnimated { + + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + MGLCoordinateBounds unitBounds = MGLCoordinateBoundsMake(CLLocationCoordinate2DMake(0, 0), CLLocationCoordinate2DMake(1, 1)); + MGLMapCamera *camera = [strongSelf.mapView cameraThatFitsCoordinateBounds:unitBounds]; + + [strongSelf.mapView flyToCamera:camera withDuration:0.3 completionHandler:completion]; + } + else { + completion(); + } + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:nil]; +} + + +#pragma mark - test interrupting regular rendering + +- (void)testSetCenterCoordinateSetHidden { + + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + [strongSelf.mapView setCenterCoordinate:CLLocationCoordinate2DMake(10.0, 10.0) + zoomLevel:10.0 + direction:0 + animated:NO + completionHandler:completion]; + } + else { + completion(); + } + }; + + dispatch_block_t addedToPending = ^{ + __typeof__(self) strongSelf = weakSelf; + + MGLTestAssert(strongSelf, !strongSelf.completionHandlerCalled); + + // Now hide the mapview + strongSelf.mapView.hidden = YES; + + MGLTestAssert(strongSelf, strongSelf.completionHandlerCalled); + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:addedToPending]; +} + +- (void)testSetCenterCoordinatePauseRendering { + + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + [strongSelf.mapView setCenterCoordinate:CLLocationCoordinate2DMake(10.0, 10.0) + zoomLevel:10.0 + direction:0 + animated:NO + completionHandler:completion]; + } + else { + completion(); + } + }; + + dispatch_block_t addedToPending = ^{ + __typeof__(self) strongSelf = weakSelf; + + MGLTestAssert(strongSelf, !strongSelf.completionHandlerCalled); + + // Pause rendering, stopping display link + [strongSelf.mapView pauseRendering:nil]; + + MGLTestAssert(strongSelf, strongSelf.completionHandlerCalled); + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:addedToPending]; +} + +- (void)testSetCenterCoordinateRemoveFromSuperview { + + __typeof__(self) weakSelf = self; + + void (^transition)(dispatch_block_t) = ^(dispatch_block_t completion) { + __typeof__(self) strongSelf = weakSelf; + + if (strongSelf) { + [strongSelf.mapView setCenterCoordinate:CLLocationCoordinate2DMake(10.0, 10.0) + zoomLevel:10.0 + direction:0 + animated:NO + completionHandler:completion]; + } + else { + completion(); + } + }; + + dispatch_block_t addedToPending = ^{ + __typeof__(self) strongSelf = weakSelf; + + MGLTestAssert(strongSelf, !strongSelf.completionHandlerCalled); + + // Remove from window, triggering validateDisplayLink + [strongSelf.mapView removeFromSuperview]; + + MGLTestAssert(strongSelf, strongSelf.completionHandlerCalled); + }; + + [self internalTestCompletionBlockAddedToPendingForTestName:NSStringFromSelector(_cmd) + transition:transition + addToPendingCallback:addedToPending]; +} + +#pragma mark - Shared utility methods + +- (void)internalTestCompletionBlockAddedToPendingForTestName:(NSString *)testName + transition:(void (^)(dispatch_block_t))transition + addToPendingCallback:(dispatch_block_t)addToPendingCallback { + + XCTestExpectation *expectation = [self expectationWithDescription:testName]; + + __weak __typeof__(self) myself = self; + + dispatch_block_t block = ^{ + myself.completionHandlerCalled = YES; + [expectation fulfill]; + }; + + XCTAssertNotNil(transition); + transition(block); + + XCTAssert(!self.completionHandlerCalled); + XCTAssert(self.mapView.pendingCompletionBlocks.count == 0); + + __block BOOL blockAddedToPendingBlocks = NO; + + // Observes changes to pendingCompletionBlocks (including additions) + self.observation = ^(NSDictionary *change){ + + NSLog(@"change = %@ count = %lu", change, myself.mapView.pendingCompletionBlocks.count); + + NSArray *value = change[NSKeyValueChangeNewKey]; + + MGLTestAssert(myself, [value isKindOfClass:[NSArray class]]); + + if (value.count > 0) { + MGLTestAssert(myself, [value containsObject:block]); + MGLTestAssert(myself, !blockAddedToPendingBlocks); + if ([myself.mapView.pendingCompletionBlocks containsObject:block]) { + blockAddedToPendingBlocks = YES; + + if (addToPendingCallback) { + addToPendingCallback(); + } + } + } + }; + + [self.mapView addObserver:self forKeyPath:@"pendingCompletionBlocks" options:NSKeyValueObservingOptionNew context:_cmd]; + + [self waitForExpectations:@[expectation] timeout:0.5]; + + XCTAssert(blockAddedToPendingBlocks); + XCTAssert(self.completionHandlerCalled); + XCTAssert(self.mapView.pendingCompletionBlocks.count == 0); + + [self.mapView removeObserver:self forKeyPath:@"pendingCompletionBlocks" context:_cmd]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context { + if (self.observation) { + self.observation(change); + } +} +@end |